diff --git a/Canvas.cpp b/Canvas.cpp index e4646a0..17c0632 100644 --- a/Canvas.cpp +++ b/Canvas.cpp @@ -1,5 +1,9 @@ #include "Canvas.h" +static double dist_P2P(QPointF p1, QPointF p2) { + return sqrt(pow(p2.x() - p1.x(), 2) + pow(p2.y() - p1.y(), 2)); +} + void Canvas::changeMode(Mode _mode) { mode = _mode; @@ -16,6 +20,20 @@ Line* Canvas::findAt(QPointF& pos) return nullptr; } +Point* Canvas::findPointAt(QPointF pos, qreal tolerance) +{ + for (Line* line : lines) { + QPointF p1(*line->p1.x, *line->p1.y); + QPointF p2(*line->p2.x, *line->p2.y); + + if (dist_P2P(p1, pos) <= tolerance) + return &line->p1; + else if (dist_P2P(p2, pos) <= tolerance) + return &line->p2; + } + return nullptr; +} + LinePair Canvas::makeOrderedPair(Line* l1, Line* l2) { return (l1 < l2) ? std::make_pair(l1, l2) : std::make_pair(l2, l1); @@ -102,7 +120,7 @@ void Canvas::mousePressEvent(QMouseEvent* event) #ifdef _DEBUG qDebug() << "Line" << first << "and" << found << "are parallel. Abort!"; #endif - QMessageBox::information(this, + QMessageBox::warning(this, QString("Wrong"), QString("Parallel lines can not be more parallel!"), QMessageBox::Ok @@ -113,6 +131,43 @@ void Canvas::mousePressEvent(QMouseEvent* event) update(); } + + else if (mode == Mode::Coincedent) { + Point* clickedPoint = findPointAt(scene); + + if (!clickedPoint) { + firstPoint = nullptr; + return; + } + + if (!firstPoint) { + firstPoint = clickedPoint; + return; + } + + if (clickedPoint == firstPoint) { + firstPoint = nullptr; + return; + } + + Line *l1 = nullptr, *l2 = nullptr; + for (Line* l : lines) { + if (&l->p1 == firstPoint || &l->p2 == firstPoint) l1 = l; + if (&l->p1 == clickedPoint || &l->p2 == clickedPoint) l2 = l; + } + + if (l1 == l2) { + QMessageBox::warning(this, QString("NO!"), QString("P2P failed")); + firstPoint = nullptr; + return; + } + + sys.addConstraintP2PCoincident(*firstPoint, *clickedPoint, constraints_count++); + firstPoint = nullptr; + mode = Mode::None; + update(); + return; + } } void Canvas::paintEvent(QPaintEvent*) @@ -163,5 +218,7 @@ Canvas::~Canvas() if (current_line) delete current_line; + if (firstPoint) + delete firstPoint; } diff --git a/Canvas.h b/Canvas.h index 1f0da0f..9cc0fdd 100644 --- a/Canvas.h +++ b/Canvas.h @@ -18,7 +18,8 @@ enum class Mode : int { None = 0, DrawingLine = 1, - Parallel = 2 + Parallel = 2, + Coincedent = 3 }; // Удобный тип для хранения пары параллельных линий (порядок не важен) @@ -45,6 +46,7 @@ protected: private: // ====================== Поиск и выбор ====================== Line* findAt(QPointF&); // ищет линию под курсором + Point* findPointAt(QPointF, qreal tolerance = 10.0); // ====================== Параллельность ====================== LinePair makeOrderedPair(Line* l1, Line* l2); @@ -59,6 +61,7 @@ private: std::set parallelPairs; // уже запараллеленные пары (защита от дублей) Line* current_line{ nullptr }; + Point* firstPoint{ nullptr }; Mode mode{ Mode::None }; int obj_count{ 0 }; // тег для новых объектов diff --git a/DRAWer_2_0.cpp b/DRAWer_2_0.cpp index 9f9ec8c..8bcc487 100644 --- a/DRAWer_2_0.cpp +++ b/DRAWer_2_0.cpp @@ -26,6 +26,6 @@ void DRAWer_2_0::on_pushButton_2_clicked() void DRAWer_2_0::on_pushButton_3_clicked() { - return; + ui.widget->changeMode(Mode::Coincedent); }