Отладка перпендикулярности
Перенос солвера для canvas в отдельную функцию (краш на QPen)
This commit is contained in:
111
Canvas.cpp
111
Canvas.cpp
@@ -1,4 +1,6 @@
|
||||
#include "Canvas.h"
|
||||
#define WIDGET_POSITION event->pos()
|
||||
#define UCS_POSITION screenToLogical(WIDGET_POSITION)
|
||||
|
||||
// ===================================================================
|
||||
// Вспомогательные функции
|
||||
@@ -181,6 +183,12 @@ void Canvas::remove_constraint(int tag)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Mode::Perpendicular: {
|
||||
if (auto* pair = std::get_if<LinePair>(&info.data)) {
|
||||
perpendicularPairs.erase(*pair);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -259,7 +267,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
VERT_pairs.insert(pair);
|
||||
C_Info[constraints_count - 1] = { Mode::Vertical, pair };
|
||||
}
|
||||
update();
|
||||
solve_for_canvas();
|
||||
after_constraint = true;
|
||||
}
|
||||
mode = Mode::None;
|
||||
@@ -320,7 +328,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
mode = Mode::None;
|
||||
QMessageBox::critical(this, "WHOOPS",
|
||||
"Sorry, your line is very short", QMessageBox::Ok);
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -335,7 +343,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
obj_count++;
|
||||
after_constraint = true;
|
||||
}
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -345,21 +353,21 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
|
||||
if (!found) {
|
||||
current_line = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
// Первый клик: выбираем первую линию
|
||||
if (!current_line) {
|
||||
current_line = found;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
// Повторный клик на ту же линию: сброс выбора
|
||||
if (found == current_line) {
|
||||
current_line = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -373,7 +381,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
current_line = nullptr;
|
||||
mode = Mode::None;
|
||||
after_constraint = true;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
}
|
||||
else {
|
||||
// Линии уже параллельны - сообщаем об ошибке
|
||||
@@ -387,7 +395,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
QMessageBox::Ok
|
||||
);
|
||||
current_line = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -397,21 +405,21 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
Point* clickedPoint = findPointAt(scene);
|
||||
if (!clickedPoint) {
|
||||
firstPoint = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
// Первый клик: выбираем первую точку
|
||||
if (!firstPoint) {
|
||||
firstPoint = clickedPoint;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
// Повторный клик на ту же точку: сброс выбора
|
||||
if (clickedPoint == firstPoint) {
|
||||
firstPoint = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -430,7 +438,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
QMessageBox::critical(this, QString("NO!"), QString("P2P failed"));
|
||||
firstPoint = nullptr;
|
||||
mode = Mode::None;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -443,7 +451,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
firstPoint = nullptr;
|
||||
mode = Mode::None;
|
||||
after_constraint = true;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -452,21 +460,21 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
|
||||
if (!found) {
|
||||
current_line = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
// Первый клик: выбираем первую линию
|
||||
if (!current_line) {
|
||||
current_line = found;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
// Повторный клик на ту же линию: сброс выбора
|
||||
if (found == current_line) {
|
||||
current_line = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -474,11 +482,12 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
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;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -488,7 +497,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
QMessageBox::Ok
|
||||
);
|
||||
current_line = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -500,6 +509,9 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
|
||||
if (draggedPoint) {
|
||||
QPointF pos = UCS_POSITION - dragOffset;
|
||||
|
||||
*draggedPoint->x = pos.x();
|
||||
*draggedPoint->y = pos.y();
|
||||
|
||||
// TODO
|
||||
for (Point* pair : points) {
|
||||
if (areCoincident(draggedPoint, pair)) {
|
||||
@@ -525,9 +537,16 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
*draggedPoint->x = pos.x();
|
||||
*draggedPoint->y = pos.y();
|
||||
update();
|
||||
for (Point* other : points) {
|
||||
if (areHorizontalVertical(draggedPoint, other, true)) {
|
||||
*other->x = pos.x();
|
||||
}
|
||||
if (areHorizontalVertical(draggedPoint, other, false)) {
|
||||
*other->y = pos.y();
|
||||
}
|
||||
}
|
||||
|
||||
solve_for_canvas();
|
||||
}
|
||||
|
||||
// ====================== Перемещение линии ======================
|
||||
@@ -559,7 +578,7 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
solve_for_canvas();
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else
|
||||
@@ -573,12 +592,12 @@ void Canvas::mouseReleaseEvent(QMouseEvent* event)
|
||||
|
||||
if (draggedPoint) {
|
||||
draggedPoint = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
}
|
||||
|
||||
if (draggedLine) {
|
||||
draggedLine = nullptr;
|
||||
update();
|
||||
solve_for_canvas();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,23 +618,6 @@ void Canvas::paintEvent(QPaintEvent* event)
|
||||
p.drawLine(-5, 0, 5, 0);
|
||||
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_constraint(constraints_count - 1);
|
||||
constraints_count--;
|
||||
}
|
||||
after_constraint = false;
|
||||
}
|
||||
|
||||
// ====================== Отрисовка линий ======================
|
||||
for (Line* line : lines) {
|
||||
bool isSelected = (mode == Mode::Parallel && line == current_line);
|
||||
@@ -708,3 +710,30 @@ std::vector<Point*> Canvas::getCoincidentGroup(Point* p)
|
||||
}
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user