Perpendicular #7
198
Canvas.cpp
198
Canvas.cpp
@@ -1,4 +1,6 @@
|
|||||||
#include "Canvas.h"
|
#include "Canvas.h"
|
||||||
|
#define WIDGET_POSITION event->pos()
|
||||||
|
#define UCS_POSITION screenToLogical(WIDGET_POSITION)
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
// Вспомогательные функции
|
// Вспомогательные функции
|
||||||
@@ -78,7 +80,6 @@ void Canvas::changeMode(Mode _mode)
|
|||||||
|
|
||||||
Line* Canvas::findAt(QPointF& pos, qreal tolerance)
|
Line* Canvas::findAt(QPointF& pos, qreal tolerance)
|
||||||
{
|
{
|
||||||
// TODO: реализовать проверку, находится ли точка на линии
|
|
||||||
for (Line* line : lines) {
|
for (Line* line : lines) {
|
||||||
if (line->contains(pos, tolerance)) {
|
if (line->contains(pos, tolerance)) {
|
||||||
return line;
|
return line;
|
||||||
@@ -136,48 +137,62 @@ bool Canvas::areAlreadyParallel(Line* l1, Line* l2)
|
|||||||
return parallelPairs.count(makeOrderedPair<LinePair>(l1, l2));
|
return parallelPairs.count(makeOrderedPair<LinePair>(l1, l2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Canvas::areAlreadyPerpendicular(Line* line1, Line* line2)
|
||||||
|
{
|
||||||
|
return perpendicularPairs.count(makeOrderedPair<LinePair>(line1, line2));
|
||||||
|
}
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
// Методы работы с ограничениями
|
// Методы работы с ограничениями
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|
||||||
void Canvas::remove_constraints()
|
// TODO - переделать в bool для отображения статуса выполнения
|
||||||
|
void Canvas::remove_constraint(int tag)
|
||||||
{
|
{
|
||||||
|
auto it = C_Info.find(tag);
|
||||||
|
if (it == C_Info.end()) return;
|
||||||
|
|
||||||
|
ConstraintInfo info = it->second;
|
||||||
|
|
||||||
// Удаляем ограничение из солвера
|
// Удаляем ограничение из солвера
|
||||||
sys.clearByTag(constraints_count - 1);
|
sys.clearByTag(tag);
|
||||||
|
|
||||||
// Удаляем из соответствующих контейнеров в зависимости от типа ограничения
|
// Удаляем из соответствующих контейнеров в зависимости от типа ограничения
|
||||||
switch (lastConstraint.mode) {
|
switch (info.mode) {
|
||||||
case Mode::Horizontal: {
|
case Mode::Horizontal: {
|
||||||
if (auto* pair = std::get_if<PointPair>(&lastConstraint.data)) {
|
if (auto* pair = std::get_if<PointPair>(&info.data)) {
|
||||||
HORIZ_pairs.erase(*pair);
|
HORIZ_pairs.erase(*pair);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Mode::Vertical: {
|
case Mode::Vertical: {
|
||||||
if (auto* pair = std::get_if<PointPair>(&lastConstraint.data)) {
|
if (auto* pair = std::get_if<PointPair>(&info.data)) {
|
||||||
VERT_pairs.erase(*pair);
|
VERT_pairs.erase(*pair);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Mode::Parallel: {
|
case Mode::Parallel: {
|
||||||
if (auto* pair = std::get_if<LinePair>(&lastConstraint.data)) {
|
if (auto* pair = std::get_if<LinePair>(&info.data)) {
|
||||||
parallelPairs.erase(*pair);
|
parallelPairs.erase(*pair);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Mode::Coincedent: {
|
case Mode::Coincedent: {
|
||||||
if (auto* pair = std::get_if<PointPair>(&lastConstraint.data)) {
|
if (auto* pair = std::get_if<PointPair>(&info.data)) {
|
||||||
P2Ppairs.erase(*pair);
|
P2Ppairs.erase(*pair);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Mode::Perpendicular: {
|
||||||
|
if (auto* pair = std::get_if<LinePair>(&info.data)) {
|
||||||
|
perpendicularPairs.erase(*pair);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
C_Info.erase(it);
|
||||||
// Сбрасываем информацию о последнем ограничении
|
|
||||||
lastConstraint.mode = Mode::None;
|
|
||||||
constraints_count--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
@@ -244,17 +259,15 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
sys.addConstraintHorizontal(*found, constraints_count++);
|
sys.addConstraintHorizontal(*found, constraints_count++);
|
||||||
auto pair = makeOrderedPair<PointPair>(found->start_ref, found->end_ref);
|
auto pair = makeOrderedPair<PointPair>(found->start_ref, found->end_ref);
|
||||||
HORIZ_pairs.insert(pair);
|
HORIZ_pairs.insert(pair);
|
||||||
lastConstraint.mode = Mode::Horizontal;
|
C_Info[constraints_count - 1] = { Mode::Horizontal, pair };
|
||||||
lastConstraint.data = pair;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sys.addConstraintVertical(*found, constraints_count++);
|
sys.addConstraintVertical(*found, constraints_count++);
|
||||||
auto pair = makeOrderedPair<PointPair>(found->start_ref, found->end_ref);
|
auto pair = makeOrderedPair<PointPair>(found->start_ref, found->end_ref);
|
||||||
VERT_pairs.insert(pair);
|
VERT_pairs.insert(pair);
|
||||||
lastConstraint.mode = Mode::Vertical;
|
C_Info[constraints_count - 1] = { Mode::Vertical, pair };
|
||||||
lastConstraint.data = pair;
|
|
||||||
}
|
}
|
||||||
update();
|
solve_for_canvas();
|
||||||
after_constraint = true;
|
after_constraint = true;
|
||||||
}
|
}
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
@@ -315,7 +328,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
QMessageBox::critical(this, "WHOOPS",
|
QMessageBox::critical(this, "WHOOPS",
|
||||||
"Sorry, your line is very short", QMessageBox::Ok);
|
"Sorry, your line is very short", QMessageBox::Ok);
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +343,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
obj_count++;
|
obj_count++;
|
||||||
after_constraint = true;
|
after_constraint = true;
|
||||||
}
|
}
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,21 +353,21 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
current_line = nullptr;
|
current_line = nullptr;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Первый клик: выбираем первую линию
|
// Первый клик: выбираем первую линию
|
||||||
if (!current_line) {
|
if (!current_line) {
|
||||||
current_line = found;
|
current_line = found;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Повторный клик на ту же линию: сброс выбора
|
// Повторный клик на ту же линию: сброс выбора
|
||||||
if (found == current_line) {
|
if (found == current_line) {
|
||||||
current_line = nullptr;
|
current_line = nullptr;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,13 +376,12 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
auto pair = makeOrderedPair<LinePair>(found, current_line);
|
auto pair = makeOrderedPair<LinePair>(found, current_line);
|
||||||
sys.addConstraintParallel(*found, *current_line, constraints_count++);
|
sys.addConstraintParallel(*found, *current_line, constraints_count++);
|
||||||
parallelPairs.insert(pair);
|
parallelPairs.insert(pair);
|
||||||
lastConstraint.mode = Mode::Parallel;
|
C_Info[constraints_count - 1] = { Mode::Parallel, pair };
|
||||||
lastConstraint.data = pair;
|
|
||||||
|
|
||||||
current_line = nullptr;
|
current_line = nullptr;
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
after_constraint = true;
|
after_constraint = true;
|
||||||
update();
|
solve_for_canvas();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Линии уже параллельны - сообщаем об ошибке
|
// Линии уже параллельны - сообщаем об ошибке
|
||||||
@@ -383,7 +395,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
QMessageBox::Ok
|
QMessageBox::Ok
|
||||||
);
|
);
|
||||||
current_line = nullptr;
|
current_line = nullptr;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -393,21 +405,21 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
Point* clickedPoint = findPointAt(scene);
|
Point* clickedPoint = findPointAt(scene);
|
||||||
if (!clickedPoint) {
|
if (!clickedPoint) {
|
||||||
firstPoint = nullptr;
|
firstPoint = nullptr;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Первый клик: выбираем первую точку
|
// Первый клик: выбираем первую точку
|
||||||
if (!firstPoint) {
|
if (!firstPoint) {
|
||||||
firstPoint = clickedPoint;
|
firstPoint = clickedPoint;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Повторный клик на ту же точку: сброс выбора
|
// Повторный клик на ту же точку: сброс выбора
|
||||||
if (clickedPoint == firstPoint) {
|
if (clickedPoint == firstPoint) {
|
||||||
firstPoint = nullptr;
|
firstPoint = nullptr;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,7 +438,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
QMessageBox::critical(this, QString("NO!"), QString("P2P failed"));
|
QMessageBox::critical(this, QString("NO!"), QString("P2P failed"));
|
||||||
firstPoint = nullptr;
|
firstPoint = nullptr;
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,15 +446,61 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
sys.addConstraintP2PCoincident(*clickedPoint, *firstPoint, constraints_count++);
|
sys.addConstraintP2PCoincident(*clickedPoint, *firstPoint, constraints_count++);
|
||||||
auto pair = makeOrderedPair<PointPair>(clickedPoint, firstPoint);
|
auto pair = makeOrderedPair<PointPair>(clickedPoint, firstPoint);
|
||||||
P2Ppairs.insert(pair);
|
P2Ppairs.insert(pair);
|
||||||
lastConstraint.mode = Mode::Coincedent;
|
C_Info[constraints_count - 1] = { Mode::Coincedent, pair };
|
||||||
lastConstraint.data = pair;
|
|
||||||
|
|
||||||
firstPoint = nullptr;
|
firstPoint = nullptr;
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
after_constraint = true;
|
after_constraint = true;
|
||||||
update();
|
solve_for_canvas();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (mode == Mode::Perpendicular) {
|
||||||
|
Line* found = findAt(scene);
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
current_line = nullptr;
|
||||||
|
solve_for_canvas();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Первый клик: выбираем первую линию
|
||||||
|
if (!current_line) {
|
||||||
|
current_line = found;
|
||||||
|
solve_for_canvas();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Повторный клик на ту же линию: сброс выбора
|
||||||
|
if (found == current_line) {
|
||||||
|
current_line = nullptr;
|
||||||
|
solve_for_canvas();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!areAlreadyPerpendicular(found, current_line)) {
|
||||||
|
auto pair = makeOrderedPair<LinePair>(found, current_line);
|
||||||
|
sys.addConstraintPerpendicular(*found, *current_line, constraints_count++);
|
||||||
|
perpendicularPairs.insert(pair);
|
||||||
|
C_Info[constraints_count - 1] = { Mode::Perpendicular, pair };
|
||||||
|
|
||||||
|
current_line = nullptr;
|
||||||
|
mode = Mode::None;
|
||||||
|
after_constraint = true;
|
||||||
|
solve_for_canvas();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
QMessageBox::warning(this,
|
||||||
|
QString("Wrong"),
|
||||||
|
QString("Perpendicular lines can not be more perpendicular!"),
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
|
current_line = nullptr;
|
||||||
|
solve_for_canvas();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::mouseMoveEvent(QMouseEvent* event)
|
void Canvas::mouseMoveEvent(QMouseEvent* event)
|
||||||
@@ -451,8 +509,18 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
|
|||||||
if (draggedPoint) {
|
if (draggedPoint) {
|
||||||
QPointF pos = UCS_POSITION - dragOffset;
|
QPointF pos = UCS_POSITION - dragOffset;
|
||||||
|
|
||||||
auto coincidentGroup = getCoincidentGroup(draggedPoint);
|
*draggedPoint->x = pos.x();
|
||||||
|
*draggedPoint->y = pos.y();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
for (Point* pair : points) {
|
||||||
|
if (areCoincident(draggedPoint, pair)) {
|
||||||
|
*pair->x = pos.x();
|
||||||
|
*pair->y = pos.y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto coincidentGroup = getCoincidentGroup(draggedPoint);
|
||||||
for (Point* pt : coincidentGroup) {
|
for (Point* pt : coincidentGroup) {
|
||||||
*pt->x = pos.x();
|
*pt->x = pos.x();
|
||||||
*pt->y = pos.y();
|
*pt->y = pos.y();
|
||||||
@@ -469,9 +537,16 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*draggedPoint->x = pos.x();
|
for (Point* other : points) {
|
||||||
*draggedPoint->y = pos.y();
|
if (areHorizontalVertical(draggedPoint, other, true)) {
|
||||||
update();
|
*other->x = pos.x();
|
||||||
|
}
|
||||||
|
if (areHorizontalVertical(draggedPoint, other, false)) {
|
||||||
|
*other->y = pos.y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
solve_for_canvas();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====================== Перемещение линии ======================
|
// ====================== Перемещение линии ======================
|
||||||
@@ -503,7 +578,7 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update();
|
solve_for_canvas();
|
||||||
}
|
}
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
else
|
else
|
||||||
@@ -517,12 +592,12 @@ void Canvas::mouseReleaseEvent(QMouseEvent* event)
|
|||||||
|
|
||||||
if (draggedPoint) {
|
if (draggedPoint) {
|
||||||
draggedPoint = nullptr;
|
draggedPoint = nullptr;
|
||||||
update();
|
solve_for_canvas();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draggedLine) {
|
if (draggedLine) {
|
||||||
draggedLine = nullptr;
|
draggedLine = nullptr;
|
||||||
update();
|
solve_for_canvas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,22 +618,6 @@ void Canvas::paintEvent(QPaintEvent* event)
|
|||||||
p.drawLine(-5, 0, 5, 0);
|
p.drawLine(-5, 0, 5, 0);
|
||||||
p.drawLine(0, -5, 0, 5);
|
p.drawLine(0, -5, 0, 5);
|
||||||
|
|
||||||
|
|
||||||
// ====================== Решение системы уравнений ======================
|
|
||||||
if (!params.empty()) {
|
|
||||||
int res = sys.solve(params);
|
|
||||||
if (res == SolveStatus::Success || res == SolveStatus::Converged) {
|
|
||||||
sys.applySolution();
|
|
||||||
}
|
|
||||||
else if (res == SolveStatus::Failed && after_constraint) {
|
|
||||||
// Ошибка решения: удаляем последнее добавленное ограничение
|
|
||||||
QMessageBox::warning(this, QString("Error!"),
|
|
||||||
QString("Last constraint is unavailable!"));
|
|
||||||
remove_constraints();
|
|
||||||
}
|
|
||||||
after_constraint = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ====================== Отрисовка линий ======================
|
// ====================== Отрисовка линий ======================
|
||||||
for (Line* line : lines) {
|
for (Line* line : lines) {
|
||||||
bool isSelected = (mode == Mode::Parallel && line == current_line);
|
bool isSelected = (mode == Mode::Parallel && line == current_line);
|
||||||
@@ -651,3 +710,30 @@ std::vector<Point*> Canvas::getCoincidentGroup(Point* p)
|
|||||||
}
|
}
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Canvas::solve_for_canvas()
|
||||||
|
{
|
||||||
|
bool flag = false;
|
||||||
|
int res = sys.solve(params);
|
||||||
|
if (res != SolveStatus::Success && res != SolveStatus::Converged) {
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sys.applySolution();
|
||||||
|
for (Line* line : lines) {
|
||||||
|
if (abs(*line->p1.x - *line->p2.x) < EPS && abs(*line->p1.y - *line->p2.y) < EPS && after_constraint) {
|
||||||
|
sys.undoSolution();
|
||||||
|
flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
QMessageBox::warning(this, QString("Error!"), QString("Last constraint is unavailable!"));
|
||||||
|
remove_constraint(constraints_count - 1);
|
||||||
|
constraints_count--;
|
||||||
|
}
|
||||||
|
after_constraint = false;
|
||||||
|
update();
|
||||||
|
}
|
||||||
24
Canvas.h
24
Canvas.h
@@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
constexpr auto EPS = 1e-9;
|
||||||
#define WIDGET_POSITION event->pos()
|
|
||||||
#define UCS_POSITION screenToLogical(WIDGET_POSITION)
|
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
@@ -30,7 +28,8 @@ enum class Mode : int
|
|||||||
Parallel = 2, ///< Режим задания параллельности
|
Parallel = 2, ///< Режим задания параллельности
|
||||||
Coincedent = 3, ///< Режим задания совпадения точек
|
Coincedent = 3, ///< Режим задания совпадения точек
|
||||||
Horizontal = 4, ///< Режим задания горизонтальности
|
Horizontal = 4, ///< Режим задания горизонтальности
|
||||||
Vertical = 5 ///< Режим задания вертикальности
|
Vertical = 5, ///< Режим задания вертикальности
|
||||||
|
Perpendicular = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Удобный тип для хранения пары параллельных линий (порядок не важен)
|
/// Удобный тип для хранения пары параллельных линий (порядок не важен)
|
||||||
@@ -94,10 +93,12 @@ private:
|
|||||||
/// Проверить, являются ли две линии уже параллельными (дубликат ограничения)
|
/// Проверить, являются ли две линии уже параллельными (дубликат ограничения)
|
||||||
bool areAlreadyParallel(Line* line1, Line* line2);
|
bool areAlreadyParallel(Line* line1, Line* line2);
|
||||||
|
|
||||||
|
bool areAlreadyPerpendicular(Line* line1, Line* line2);
|
||||||
|
|
||||||
// ====================== Методы работы с ограничениями ======================
|
// ====================== Методы работы с ограничениями ======================
|
||||||
|
|
||||||
/// Удалить последние добавленные ограничения при ошибке солвера
|
/// Удалить последние добавленные ограничения при ошибке солвера
|
||||||
void remove_constraints();
|
void remove_constraint(int);
|
||||||
|
|
||||||
// ====================== Данные для перемещения объектов ======================
|
// ====================== Данные для перемещения объектов ======================
|
||||||
|
|
||||||
@@ -115,6 +116,7 @@ private:
|
|||||||
// ====================== Коллекции ограничений ======================
|
// ====================== Коллекции ограничений ======================
|
||||||
|
|
||||||
std::set<LinePair> parallelPairs; ///< Пары параллельных линий
|
std::set<LinePair> parallelPairs; ///< Пары параллельных линий
|
||||||
|
std::set<LinePair> perpendicularPairs;
|
||||||
std::set<PointPair> P2Ppairs; ///< Пары совпадающих точек
|
std::set<PointPair> P2Ppairs; ///< Пары совпадающих точек
|
||||||
std::set<PointPair> HORIZ_pairs; ///< Пары точек горизонтальных линий
|
std::set<PointPair> HORIZ_pairs; ///< Пары точек горизонтальных линий
|
||||||
std::set<PointPair> VERT_pairs; ///< Пары точек вертикальных линий
|
std::set<PointPair> VERT_pairs; ///< Пары точек вертикальных линий
|
||||||
@@ -138,10 +140,12 @@ private:
|
|||||||
|
|
||||||
/// Структура для хранения информации о последнем добавленном ограничении
|
/// Структура для хранения информации о последнем добавленном ограничении
|
||||||
/// (используется для отката при ошибке солвера)
|
/// (используется для отката при ошибке солвера)
|
||||||
struct LastConstraint {
|
|
||||||
Mode mode{ Mode::None }; ///< Тип последнего ограничения
|
|
||||||
std::variant<LinePair, PointPair> data; ///< Данные ограничения
|
|
||||||
};
|
|
||||||
|
|
||||||
LastConstraint lastConstraint; ///< Информация о последнем добавленном ограничении
|
struct ConstraintInfo {
|
||||||
|
Mode mode;
|
||||||
|
std::variant<LinePair, PointPair> data;
|
||||||
|
};
|
||||||
|
std::map<int, ConstraintInfo> C_Info;
|
||||||
|
|
||||||
|
void solve_for_canvas();
|
||||||
};
|
};
|
||||||
@@ -40,3 +40,9 @@ void DRAWer_2_0::on_Vertical_Button_clicked()
|
|||||||
ui.widget->changeMode(Mode::Vertical);
|
ui.widget->changeMode(Mode::Vertical);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DRAWer_2_0::on_Perpendicular_Button_clicked()
|
||||||
|
{
|
||||||
|
ui.widget->changeMode(Mode::Perpendicular);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ private slots:
|
|||||||
|
|
||||||
void on_Vertical_Button_clicked();
|
void on_Vertical_Button_clicked();
|
||||||
|
|
||||||
|
void on_Perpendicular_Button_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::DRAWer_2_0Class ui;
|
Ui::DRAWer_2_0Class ui;
|
||||||
int counter;
|
int counter;
|
||||||
|
|||||||
@@ -52,6 +52,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="Perpendicular_Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Perpendicular</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="P2P_Button">
|
<widget class="QPushButton" name="P2P_Button">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
|
|||||||
Reference in New Issue
Block a user