Browse Source

First version.

Rémi Synave 2 years ago
parent
commit
aee10e22a9
8 changed files with 625 additions and 0 deletions
  1. 88 0
      src/MainWindow.cpp
  2. 39 0
      src/MainWindow.hpp
  3. 239 0
      src/StrengthLine.cpp
  4. 21 0
      src/StrengthLine.hpp
  5. 161 0
      src/WorkArea.cpp
  6. 51 0
      src/WorkArea.hpp
  7. 14 0
      src/dsl.pro
  8. 12 0
      src/main.cpp

+ 88 - 0
src/MainWindow.cpp

@@ -0,0 +1,88 @@
+#include <QDebug>
+
+#include <QGuiApplication>
+#include <QScreen>
+#include <QWidget>
+#include <QMenuBar>
+#include <QFileDialog>
+#include <QSizePolicy>
+
+#include <QWidget>
+#include <QHBoxLayout>
+
+#include "MainWindow.hpp"
+
+
+MainWindow::MainWindow ()
+{
+  createActions ();
+  createMenus ();
+
+  setWindowTitle (tr ("DSL - Draw Strength Line"));
+
+  QScreen *screen = QGuiApplication::primaryScreen ();
+  QRect screenGeometry = screen->geometry ();
+  int screenHeight = screenGeometry.height () - 200;
+  int screenWidth = screenGeometry.width () - 200;
+
+  wa = new WorkArea (screenWidth, screenHeight, this);
+  
+  setCentralWidget (wa);
+
+  setFixedSize (screenWidth, screenHeight);
+}
+
+void
+MainWindow::open ()
+{
+  QString filename = QFileDialog::getOpenFileName (this,
+						   QObject::
+						   tr ("Open image file"),
+						   QDir::currentPath (),
+						   QObject::
+						   tr
+						   ("Images files (*.jpg *.png);;All files (*.*)"));
+  wa->loadImage (filename.toStdString ());
+  setFixedSize (wa->geometry().width(), wa->geometry().height()+wa->geometry().y());
+}
+
+void
+MainWindow::save ()
+{
+  QString filename = QFileDialog::getSaveFileName (this,
+						   QObject::tr ("Save file"),
+						   QDir::currentPath (),
+						   QObject::
+						   tr
+						   ("Text file (*.txt);;All files (*.*)"));
+  wa->saveStrengthLine (filename.toStdString ());
+}
+
+
+void
+MainWindow::createActions ()
+{
+  openAct = new QAction (tr ("&Open image"), this);
+  openAct->setShortcuts (QKeySequence::Open);
+  connect (openAct, &QAction::triggered, this, &MainWindow::open);
+
+  saveAct = new QAction (tr ("&Save"), this);
+  saveAct->setShortcuts (QKeySequence::Save);
+  connect (saveAct, &QAction::triggered, this, &MainWindow::save);
+
+  exitAct = new QAction (tr ("E&xit"), this);
+  exitAct->setShortcuts (QKeySequence::Quit);
+  connect (exitAct, &QAction::triggered, this, &QWidget::close);
+}
+
+void
+MainWindow::createMenus ()
+{
+  fileMenu = menuBar ()->addMenu (tr ("&File"));
+  fileMenu->addAction (openAct);
+  fileMenu->addAction (saveAct);
+
+  fileMenu->addSeparator ();
+
+  fileMenu->addAction (exitAct);
+}

+ 39 - 0
src/MainWindow.hpp

@@ -0,0 +1,39 @@
+#ifndef MAINWINDOW_HPP
+#define MAINWINDOW_HPP
+
+#include <QMainWindow>
+#include <QAction>
+#include <QMenu>
+
+#include "WorkArea.hpp"
+
+
+class MainWindow:public QMainWindow
+{
+  Q_OBJECT 
+
+
+private:
+  QMenu *fileMenu;
+
+  QAction *openAct;
+  QAction *saveAct;
+  QAction *exitAct;
+
+  WorkArea *wa;
+
+  void createActions ();
+  void createMenus ();
+
+		     
+private slots:
+  void open ();
+  void save ();
+
+  
+public:
+  MainWindow ();
+  
+};
+
+#endif

+ 239 - 0
src/StrengthLine.cpp

@@ -0,0 +1,239 @@
+#include <stdexcept>
+
+#include "StrengthLine.hpp"
+
+StrengthLine::StrengthLine (QPoint * p1, QPoint * p2)
+{
+  if (p1 == NULL || p2 == NULL)
+    throw std::
+      invalid_argument ("Points defining a strength line can't be NULL.");
+  if (p1->x () == p2->x () && p1->y () == p2->y ())
+    throw std::
+      invalid_argument ("Points defining a strength line can't be equals.");
+
+  this->p1 = p1;
+  this->p2 = p2;
+}
+
+std::pair < float, float >
+StrengthLine::equation () const
+{
+  // This method can be called only if a and b are
+  // not aligned into a vertical or horizontal line
+  float a = ((p1->y () - p2->y ()) * 1.0) / (p1->x () - p2->x ());
+  float b = p1->y () - a * p1->x ();
+  return std::make_pair (a, b);
+}
+
+std::pair < QPoint *, QPoint * >StrengthLine::toDraw (QImage * img) const
+{
+  // Methode qui va calculer les points pour l'affichage des droites
+  // sur l'image passées en paramètre. Calcul rapide donc
+  // les points peuvent sortir de l'image.
+
+  // ligne verticale
+  if (p1->x () == p2->x ())
+    return std::make_pair (new QPoint (p1->x (), 0),
+			   new QPoint (p1->x (), img->height ()));
+
+  // ligne horizontale
+  if (p1->y () == p2->y ())
+    return std::make_pair (new QPoint (0, p1->y ()),
+			   new QPoint (img->width (), p1->y ()));
+
+  // Equation de la droite et on prend les points gauche et droite de la ligne
+  std::pair < float, float >
+    eq = this->equation ();
+  float
+    a = std::get < 0 > (eq);
+  float
+    b = std::get < 1 > (eq);
+
+  return std::make_pair (new QPoint (0, b),
+			 new QPoint (img->width (), a * img->width () + b));
+}
+
+std::pair < QPoint *, QPoint * >StrengthLine::interpolateToEdge (QImage * img) const
+{
+  // Methode qui va calculer les points sur les bords des images
+  // en fonction des deux points attributs qui définissent
+  // la ligne.
+
+  // ligne verticale
+  if (p1->x () == p2->x ())
+    return std::make_pair (new QPoint (p1->x (), 0),
+			   new QPoint (p1->x (), img->height ()));
+
+  // ligne horizontale
+  if (p1->y () == p2->y ())
+    return std::make_pair (new QPoint (0, p1->y ()),
+			   new QPoint (img->width (), p1->y ()));
+
+  // Equation de la droite et on prend les points gauche et droite de la ligne
+  std::pair < float, float >
+    eq = this->equation ();
+  float
+    a = std::get < 0 > (eq);
+  float
+    b = std::get < 1 > (eq);
+
+  if(a>0)
+    {
+      if(b<0)
+	{
+	  if((a*img->width()+b) > img->height())
+	    {
+	      // |------------------------------------------|
+	      // |           *                              |
+	      // |           *                              |
+	      // |            *                             |
+	      // |            *                             |
+	      // |             *                            |
+	      // |             *                            |
+	      // |              *                           |
+	      // |              *                           |
+	      // |               *                          |
+	      // |------------------------------------------|
+	      
+	      return std::make_pair (new QPoint (-1*(b/a), 0),
+				     new QPoint ((img->height()-b)/a, img->height ()));
+	    }
+	  else
+	    {
+	      // |------------------------------------------|
+	      // |                           ***            |
+	      // |                              ***         |
+	      // |                                 ***      |
+	      // |                                    ***   |
+	      // |                                       ***|
+	      // |                                          |
+	      // |                                          |
+	      // |                                          |
+	      // |                                          |
+	      // |------------------------------------------|
+
+	      return std::make_pair (new QPoint (-1*(b/a), 0),
+				     new QPoint (img->width (), a * img->width () + b));
+	    }
+	}
+      else // a>0 and b>0
+	{
+	  
+	  if((a*img->width()+b) > img->height())
+	    {
+	      // |------------------------------------------|
+	      // |                                          |
+	      // |                                          |
+	      // |*                                         |
+	      // | *                                        |
+	      // |  *                                       |
+	      // |   *                                      |
+	      // |    *                                     |
+	      // |     *                                    |
+	      // |      *                                   |
+	      // |------------------------------------------|
+	      
+	      return std::make_pair (new QPoint (0, b),
+				     new QPoint ((img->height () -b )/a, img->height ()));
+	    }
+	  else
+	    {
+	      // |------------------------------------------|
+	      // |                                          |
+	      // |********                                  |
+	      // |        ********                          |
+	      // |                ********                  |
+	      // |                        ********          |
+	      // |                                ********  |
+	      // |                                        **|
+	      // |                                          |
+	      // |                                          |
+	      // |------------------------------------------|
+	      
+	      return std::make_pair (new QPoint (0, b),
+				     new QPoint (img->width(), a*img->width ()+b));
+	    }
+	}
+    }
+  else // a<0
+    {
+      if((a*img->width()+b)>0)
+	{
+	  if(b > img->height())
+	    {
+	      // |------------------------------------------|
+	      // |                                          |
+	      // |                                          |
+	      // |                                        * |
+	      // |                                      *   |
+	      // |                                    *     |
+	      // |                                  *       |
+	      // |                                *         |
+	      // |                              *           |
+	      // |                            *             |
+	      // |------------------------------------------|
+	      
+	      return std::make_pair (new QPoint ((img->height()-b)/a, img->height()),
+				     new QPoint (img->width(), a*img->width()+b));
+	    }
+	  else
+	    {
+	      // |------------------------------------------|
+	      // |                                          |
+	      // |                                          |
+	      // |                                        **|
+	      // |                                ********  |
+	      // |                        ********          |
+	      // |                ********                  |
+	      // |        ********                          |
+	      // |********                                  |
+	      // |                                          |
+	      // |------------------------------------------|
+
+	      return std::make_pair (new QPoint (0, b),
+				     new QPoint (img->width (), a * img->width () + b));
+	    }
+	}
+      else // a>0 and (a*img->width()+b) < 0
+	{
+	  
+	  if(b > img->height())
+	    {
+	      // |------------------------------------------|
+	      // |               *                          |
+	      // |               *                          |
+	      // |               *                          |
+	      // |              *                           |
+	      // |              *                           |
+	      // |              *                           |
+	      // |             *                            |
+	      // |             *                            |
+	      // |             *                            |
+	      // |------------------------------------------|
+	      
+	      return std::make_pair (new QPoint (-1*(b/a), 0),
+				     new QPoint ((img->height()-b)/a, img->height ()));
+	    }
+	  else
+	    {
+	      // |------------------------------------------|
+	      // |        *                                 |
+	      // |      *                                   |
+	      // |    *                                     |
+	      // |  *                                       |
+	      // |*                                         |
+	      // |                                          |
+	      // |                                          |
+	      // |                                          |
+	      // |                                          |
+	      // |------------------------------------------|
+	      
+	      return std::make_pair (new QPoint (0, b),
+				     new QPoint (-1*(b/a), 0));
+	    }
+	}
+    }
+  
+  return std::make_pair (new QPoint (*p1),
+			 new QPoint (*p2));
+}

+ 21 - 0
src/StrengthLine.hpp

@@ -0,0 +1,21 @@
+#ifndef STRENGTHLINE_HPP
+#define STRENGTHLINE_HPP
+
+#include <QPoint>
+#include <QImage>
+
+class StrengthLine
+{
+private:
+  QPoint * p1, *p2;
+
+  std::pair < float, float >equation () const;
+
+public:
+  StrengthLine (QPoint * p1 = new QPoint (0, 0), QPoint * p2 =
+		new QPoint (1, 1));
+  std::pair < QPoint *, QPoint * >toDraw (QImage * img) const;
+  std::pair < QPoint *, QPoint * >interpolateToEdge (QImage * img) const;
+};
+
+#endif

+ 161 - 0
src/WorkArea.cpp

@@ -0,0 +1,161 @@
+#include <QDebug>
+
+#include <QFile>
+#include <QColor>
+#include <QTextStream>
+
+#include "WorkArea.hpp"
+
+#include "StrengthLine.hpp"
+
+WorkArea::WorkArea (int screenSizeX, int screenSizeY, QWidget * parent):
+  QWidget
+{
+parent}
+
+{
+  this->screenSizeX = screenSizeX;
+  this->screenSizeY = screenSizeY;
+  indexPointClicked = -1;
+
+  img = NULL;
+}
+
+WorkArea::~WorkArea ()
+{
+}
+
+void
+WorkArea::loadImage (const std::string & filename)
+{
+  img =
+    new QImage (QImage (QString::fromStdString (filename)).
+		scaled (screenSizeX, screenSizeY - this->geometry ().y (),
+			Qt::KeepAspectRatio, Qt::FastTransformation));
+  liste_points.clear ();
+  resize (img->width (), img->height ());
+}
+
+void
+WorkArea::saveStrengthLine (const std::string & filename)
+{
+  QFile file (QString::fromStdString (filename));
+
+  if (!file.open (QIODevice::WriteOnly | QIODevice::Text))
+    return;
+
+  QTextStream out (&file);
+  for (int i = 0; i < liste_points.size () / 2; i++)
+    out << liste_points[i*2]->x () << " " << liste_points[i*2]->y () << " " << liste_points[i*2+1]->x () << " " << liste_points[i*2+1]->y () << "\n";
+
+  file.close ();
+}
+
+
+void
+WorkArea::paintEvent (QPaintEvent * event)
+{
+  QPainter painter (this);
+  paint (painter);
+}
+
+void
+WorkArea::paint (QPainter & painter)
+{
+  if (img != NULL)
+    painter.drawImage (50, 50, *img);
+
+  for (int i = 0; i < liste_points.length (); i++)
+    {
+      painter.setBrush (QBrush (Qt::green));
+      painter.setPen (QPen (Qt::black));
+      painter.drawEllipse (liste_points[i]->x () - taillePoint / 2,
+			   liste_points[i]->y () - taillePoint / 2,
+			   taillePoint, taillePoint);
+
+
+      if ((i % 2) == 1)
+	{
+	  painter.setPen (QPen (Qt::red, epaisseurLigne));
+	  std::pair < QPoint *, QPoint * >endPoints =
+	    StrengthLine (liste_points[i - 1], liste_points[i]).toDraw (img);
+	  painter.drawLine (*(std::get < 0 > (endPoints)),
+			    *(std::get < 1 > (endPoints)));
+	}
+
+    }
+
+}
+
+void
+WorkArea::mousePressEvent (QMouseEvent * event)
+{
+  if (img != NULL)
+    {
+      // Est ce qu'on a cliqué sur un point existant ?
+      indexPointClicked = -1;
+      for (int i = 0; i < liste_points.length (); i++)
+	{
+	  QPoint point = event->pos () - *(liste_points[i]);
+	  if (point.manhattanLength () < taillePoint)
+	    {
+	      indexPointClicked = i;
+	    }
+	}
+
+      // Clic gauche
+      if (event->button () == Qt::LeftButton)
+	{
+	  if (indexPointClicked == -1)
+	    {
+	      indexPointClicked = liste_points.size ();
+	      liste_points << new QPoint (event->x (), event->y ());
+	    }
+	}
+      // Clic droit
+      if (event->button () == Qt::RightButton)
+	{
+	  if (indexPointClicked != -1)
+	    {
+	      if (indexPointClicked == (liste_points.size () - 1))
+		liste_points.removeAt (indexPointClicked);
+	      else
+		{
+		  if ((indexPointClicked % 2) == 0)
+		    {
+		      QPoint *single =
+			liste_points.takeAt (indexPointClicked + 1);
+		      liste_points.removeAt (indexPointClicked);
+		      liste_points << single;
+		    }
+		  else
+		    {
+		      QPoint *single =
+			liste_points.takeAt (indexPointClicked - 1);
+		      liste_points.removeAt (indexPointClicked - 1);
+		      liste_points << single;
+		    }
+		}
+	      indexPointClicked = -1;
+	    }
+	}
+    }
+  repaint ();
+}
+
+void
+WorkArea::mouseMoveEvent (QMouseEvent * event)
+{
+  if (indexPointClicked != -1)
+    {
+      liste_points[indexPointClicked]->setX (event->x ());
+      liste_points[indexPointClicked]->setY (event->y ());
+    }
+  repaint ();
+}
+
+void
+WorkArea::mouseReleaseEvent (QMouseEvent * event)
+{
+  indexPointClicked = -1;
+}

+ 51 - 0
src/WorkArea.hpp

@@ -0,0 +1,51 @@
+#ifndef WORKAREA_HPP
+#define WORKAREA_HPP
+
+#include <string>
+
+#include <QWidget>
+#include <QPainter>
+#include <QMouseEvent>
+#include <QPoint>
+#include <QImage>
+
+
+
+class WorkArea:public QWidget
+{
+  
+  Q_OBJECT
+
+  
+private:
+  const int taillePoint = 10;
+  const int epaisseurLigne = 3;
+  
+  unsigned int screenSizeX, screenSizeY;
+  
+  QImage *img;
+  QList < QPoint * >liste_points;
+  int indexPointClicked;
+
+  
+protected:
+  void paintEvent (QPaintEvent * event) override;
+  void mousePressEvent (QMouseEvent * event);
+  void mouseMoveEvent (QMouseEvent * event);
+  void mouseReleaseEvent (QMouseEvent * event);
+
+  
+public:
+  WorkArea (int screenSizeX, int screenSizeY, QWidget * parent = nullptr);
+   ~WorkArea ();
+  
+  void paint (QPainter & painter);
+  void loadImage (const std::string & filename);
+  void saveStrengthLine (const std::string & filename);
+
+
+
+
+};
+
+#endif

+ 14 - 0
src/dsl.pro

@@ -0,0 +1,14 @@
+QT += core gui widgets
+
+HEADERS = StrengthLine.hpp \
+          WorkArea.hpp \
+          MainWindow.hpp
+                
+SOURCES = StrengthLine.cpp \
+          WorkArea.cpp \
+          MainWindow.cpp \
+          main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/dsl
+INSTALLS += target

+ 12 - 0
src/main.cpp

@@ -0,0 +1,12 @@
+#include <QApplication>
+
+#include "MainWindow.hpp"
+
+int
+main (int argc, char *argv[])
+{
+  QApplication app (argc, argv);
+  MainWindow window;
+  window.show ();
+  return app.exec ();
+}