Фикс с удалением ограничений
А ещё сделали так, чтобы линия не могла быть горизонтальной и вертикальной одновременно
This commit is contained in:
118
Canvas.cpp
118
Canvas.cpp
@@ -53,6 +53,19 @@ bool Canvas::areHorizontalVertical(Point* p1, Point* p2, bool mode)
|
|||||||
return HORIZ_pairs.count(makeOrderedPair<PointPair>(p1, p2));
|
return HORIZ_pairs.count(makeOrderedPair<PointPair>(p1, p2));
|
||||||
else
|
else
|
||||||
return VERT_pairs.count(makeOrderedPair<PointPair>(p1, p2));
|
return VERT_pairs.count(makeOrderedPair<PointPair>(p1, p2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Canvas::isLineHorizontal(Line* line)
|
||||||
|
{
|
||||||
|
if (!line || !line->start_ref || !line->end_ref) return false;
|
||||||
|
return HORIZ_pairs.count(makeOrderedPair<PointPair>(line->start_ref, line->end_ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Canvas::isLineVertical(Line* line)
|
||||||
|
{
|
||||||
|
if (!line || !line->start_ref || !line->end_ref) return false;
|
||||||
|
return VERT_pairs.count(makeOrderedPair<PointPair>(line->start_ref, line->end_ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Canvas::areAlreadyParallel(Line* l1, Line* l2)
|
bool Canvas::areAlreadyParallel(Line* l1, Line* l2)
|
||||||
@@ -60,6 +73,43 @@ bool Canvas::areAlreadyParallel(Line* l1, Line* l2)
|
|||||||
return parallelPairs.count(makeOrderedPair<LinePair>(l1, l2));
|
return parallelPairs.count(makeOrderedPair<LinePair>(l1, l2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Canvas::remove_constraints()
|
||||||
|
{
|
||||||
|
sys.clearByTag(constraints_count - 1);
|
||||||
|
|
||||||
|
switch (lastConstraint.mode) {
|
||||||
|
case Mode::Horizontal: {
|
||||||
|
if (auto* pair = std::get_if<PointPair>(&lastConstraint.data)) {
|
||||||
|
HORIZ_pairs.erase(*pair);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Mode::Vertical: {
|
||||||
|
if (auto* pair = std::get_if<PointPair>(&lastConstraint.data)) {
|
||||||
|
VERT_pairs.erase(*pair);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Mode::Parallel: {
|
||||||
|
if (auto* pair = std::get_if<LinePair>(&lastConstraint.data)) {
|
||||||
|
parallelPairs.erase(*pair);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Mode::Coincedent: {
|
||||||
|
if (auto* pair = std::get_if<PointPair>(&lastConstraint.data)) {
|
||||||
|
P2Ppairs.erase(*pair);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastConstraint.mode = Mode::None;
|
||||||
|
constraints_count--;
|
||||||
|
}
|
||||||
|
|
||||||
void Canvas::mousePressEvent(QMouseEvent* event)
|
void Canvas::mousePressEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
QPointF scene = event->pos();
|
QPointF scene = event->pos();
|
||||||
@@ -92,18 +142,45 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
Line* found = findAt(scene);
|
Line* found = findAt(scene);
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
|
if (mode == Mode::Horizontal && isLineVertical(found)) {
|
||||||
|
QMessageBox::warning(this,
|
||||||
|
QString("Невозможно"),
|
||||||
|
QString("Эта линия уже вертикальна и не может быть горизонтальной!"),
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
|
mode = Mode::None;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка: если линия уже горизонтальна, нельзя сделать её вертикальной
|
||||||
|
if (mode == Mode::Vertical && isLineHorizontal(found)) {
|
||||||
|
QMessageBox::warning(this,
|
||||||
|
QString("Невозможно"),
|
||||||
|
QString("Эта линия уже горизонтальна и не может быть вертикальной!"),
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
|
mode = Mode::None;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode == Mode::Horizontal) {
|
if (mode == Mode::Horizontal) {
|
||||||
sys.addConstraintHorizontal(*found, constraints_count++);
|
sys.addConstraintHorizontal(*found, constraints_count++);
|
||||||
HORIZ_pairs.insert(makeOrderedPair<PointPair>(found->start_ref, found->end_ref));
|
auto pair = makeOrderedPair<PointPair>(found->start_ref, found->end_ref);
|
||||||
|
HORIZ_pairs.insert(pair);
|
||||||
|
lastConstraint.mode = Mode::Horizontal;
|
||||||
|
lastConstraint.data = pair;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sys.addConstraintVertical(*found, constraints_count++);
|
sys.addConstraintVertical(*found, constraints_count++);
|
||||||
VERT_pairs.insert(makeOrderedPair<PointPair>(found->start_ref, found->end_ref));
|
auto pair = makeOrderedPair<PointPair>(found->start_ref, found->end_ref);
|
||||||
|
VERT_pairs.insert(pair);
|
||||||
|
lastConstraint.mode = Mode::Vertical;
|
||||||
|
lastConstraint.data = pair;
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
after_constraint = true;
|
||||||
}
|
}
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
after_constraint = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mode == Mode::DrawingLine) {
|
else if (mode == Mode::DrawingLine) {
|
||||||
@@ -189,12 +266,16 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!areAlreadyParallel(found, current_line)) {
|
if (!areAlreadyParallel(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(makeOrderedPair<LinePair>(found, current_line));
|
parallelPairs.insert(pair);
|
||||||
|
lastConstraint.mode = Mode::Parallel;
|
||||||
|
lastConstraint.data = pair;
|
||||||
|
|
||||||
current_line = nullptr;
|
current_line = nullptr;
|
||||||
update();
|
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
after_constraint = true;
|
after_constraint = true;
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
@@ -251,7 +332,11 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sys.addConstraintP2PCoincident(*clickedPoint, *firstPoint, constraints_count++);
|
sys.addConstraintP2PCoincident(*clickedPoint, *firstPoint, constraints_count++);
|
||||||
P2Ppairs.insert(makeOrderedPair<PointPair>(clickedPoint, firstPoint));
|
auto pair = makeOrderedPair<PointPair>(clickedPoint, firstPoint);
|
||||||
|
P2Ppairs.insert(pair);
|
||||||
|
lastConstraint.mode = Mode::Coincedent;
|
||||||
|
lastConstraint.data = pair;
|
||||||
|
|
||||||
firstPoint = nullptr;
|
firstPoint = nullptr;
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
after_constraint = true;
|
after_constraint = true;
|
||||||
@@ -338,8 +423,7 @@ void Canvas::paintEvent(QPaintEvent*)
|
|||||||
}
|
}
|
||||||
else if (res == SolveStatus::Failed && after_constraint){
|
else if (res == SolveStatus::Failed && after_constraint){
|
||||||
QMessageBox::warning(this, QString("Error!"), QString("Last constraint is unavailable!"));
|
QMessageBox::warning(this, QString("Error!"), QString("Last constraint is unavailable!"));
|
||||||
sys.removeConstraint(sys.get_last_constraint());
|
remove_constraints();
|
||||||
constraints_count--;
|
|
||||||
}
|
}
|
||||||
after_constraint = false;
|
after_constraint = false;
|
||||||
}
|
}
|
||||||
@@ -388,7 +472,6 @@ Canvas::Canvas(QWidget *parent)
|
|||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
sys = System();
|
sys = System();
|
||||||
current_line = nullptr;
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setBackgroundRole(QPalette::Base);
|
setBackgroundRole(QPalette::Base);
|
||||||
setAutoFillBackground(true);
|
setAutoFillBackground(true);
|
||||||
@@ -396,19 +479,26 @@ Canvas::Canvas(QWidget *parent)
|
|||||||
|
|
||||||
Canvas::~Canvas()
|
Canvas::~Canvas()
|
||||||
{
|
{
|
||||||
for (Line* line : lines) {
|
|
||||||
delete line;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (double* param : params) {
|
for (double* param : params) {
|
||||||
delete param;
|
delete param;
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.clear();
|
for (Point* pt : points) {
|
||||||
|
delete pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Line* line : lines) {
|
||||||
|
delete line;
|
||||||
|
}
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
points.clear();
|
points.clear();
|
||||||
|
lines.clear();
|
||||||
|
|
||||||
parallelPairs.clear();
|
parallelPairs.clear();
|
||||||
P2Ppairs.clear();
|
P2Ppairs.clear();
|
||||||
|
VERT_pairs.clear();
|
||||||
|
HORIZ_pairs.clear();
|
||||||
|
|
||||||
if (current_line)
|
if (current_line)
|
||||||
delete current_line;
|
delete current_line;
|
||||||
|
|||||||
10
Canvas.h
10
Canvas.h
@@ -54,6 +54,8 @@ private:
|
|||||||
Point* findPointAt(QPointF, qreal tolerance = 5.0);
|
Point* findPointAt(QPointF, qreal tolerance = 5.0);
|
||||||
bool areCoincident(Point*, Point*);
|
bool areCoincident(Point*, Point*);
|
||||||
bool areHorizontalVertical(Point*, Point*, bool);
|
bool areHorizontalVertical(Point*, Point*, bool);
|
||||||
|
bool isLineHorizontal(Line* line); // проверяет, горизонтальна ли линия
|
||||||
|
bool isLineVertical(Line* line); // проверяет, вертикальна ли линия
|
||||||
// ====================== Параллельность ======================
|
// ====================== Параллельность ======================
|
||||||
bool areAlreadyParallel(Line* l1, Line* l2); // проверка на дубликат
|
bool areAlreadyParallel(Line* l1, Line* l2); // проверка на дубликат
|
||||||
|
|
||||||
@@ -62,6 +64,8 @@ private:
|
|||||||
Line* draggedLine{ nullptr };
|
Line* draggedLine{ nullptr };
|
||||||
QPointF dragOffset;
|
QPointF dragOffset;
|
||||||
|
|
||||||
|
// ====================== Работа с парами ограничений ======================
|
||||||
|
void remove_constraints();
|
||||||
// ====================== Данные сцены ======================
|
// ====================== Данные сцены ======================
|
||||||
System sys; // геометрический солвер
|
System sys; // геометрический солвер
|
||||||
QVector<Line*> lines; // завершённые линии
|
QVector<Line*> lines; // завершённые линии
|
||||||
@@ -80,4 +84,10 @@ private:
|
|||||||
|
|
||||||
int obj_count{ 0 }; // тег для новых объектов
|
int obj_count{ 0 }; // тег для новых объектов
|
||||||
int constraints_count{ 0 }; // тег для новых ограничений
|
int constraints_count{ 0 }; // тег для новых ограничений
|
||||||
|
|
||||||
|
struct LastConstraint {
|
||||||
|
Mode mode{ Mode::None };
|
||||||
|
std::variant<LinePair, PointPair> data;
|
||||||
|
};
|
||||||
|
LastConstraint lastConstraint;
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user