P2P constraint fix
Но по-хорошему стоит придумать, как после P2P соединить линии одной точкой
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -365,3 +365,5 @@ FodyWeavers.xsd
|
|||||||
/include
|
/include
|
||||||
/src
|
/src
|
||||||
*.json
|
*.json
|
||||||
|
*.txt
|
||||||
|
/build
|
||||||
|
|||||||
45
Canvas.cpp
45
Canvas.cpp
@@ -9,6 +9,12 @@ void Canvas::changeMode(Mode _mode)
|
|||||||
mode = _mode;
|
mode = _mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename A, typename B>
|
||||||
|
T makeOrderedPair(A* obj1, B* obj2)
|
||||||
|
{
|
||||||
|
return (obj1->get_tag() < obj2->get_tag()) ? std::make_pair(obj1, obj2) : std::make_pair(obj2, obj1);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
Line* Canvas::findAt(QPointF& pos)
|
Line* Canvas::findAt(QPointF& pos)
|
||||||
{
|
{
|
||||||
@@ -22,26 +28,41 @@ Line* Canvas::findAt(QPointF& pos)
|
|||||||
|
|
||||||
Point* Canvas::findPointAt(QPointF pos, qreal tolerance)
|
Point* Canvas::findPointAt(QPointF pos, qreal tolerance)
|
||||||
{
|
{
|
||||||
|
Point* temp = nullptr;
|
||||||
for (Line* line : lines) {
|
for (Line* line : lines) {
|
||||||
QPointF p1(*line->p1.x, *line->p1.y);
|
QPointF p1(*line->p1.x, *line->p1.y);
|
||||||
QPointF p2(*line->p2.x, *line->p2.y);
|
QPointF p2(*line->p2.x, *line->p2.y);
|
||||||
|
|
||||||
if (dist_P2P(p1, pos) <= tolerance)
|
if (dist_P2P(p1, pos) <= tolerance)
|
||||||
return &line->p1;
|
temp = &line->p1;
|
||||||
else if (dist_P2P(p2, pos) <= tolerance)
|
else if (dist_P2P(p2, pos) <= tolerance)
|
||||||
return &line->p2;
|
temp = &line->p2;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinePair Canvas::makeOrderedPair(Line* l1, Line* l2)
|
bool Canvas::areCoincident(Point* p1, Point* p2, bool mode)
|
||||||
{
|
{
|
||||||
return (l1 < l2) ? std::make_pair(l1, l2) : std::make_pair(l2, l1);
|
int tag_0 = p1->get_tag(), tag_1 = p2->get_tag();
|
||||||
|
if (!mode){
|
||||||
|
return (tag_0 != tag_1 && *p1 == *p2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (PointPair pair : P2Ppairs) {
|
||||||
|
int pair_tag_0 = pair.first->get_tag();
|
||||||
|
int pair_tag_1 = pair.second->get_tag();
|
||||||
|
if (pair_tag_0 == tag_0 && pair_tag_1 == tag_1 ||
|
||||||
|
pair_tag_0 == tag_1 && pair_tag_1 == tag_0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Canvas::areAlreadyParallel(Line* l1, Line* l2)
|
bool Canvas::areAlreadyParallel(Line* l1, Line* l2)
|
||||||
{
|
{
|
||||||
return parallelPairs.count(makeOrderedPair(l1, l2)) > 0;
|
return parallelPairs.count(makeOrderedPair<LinePair>(l1, l2)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::mousePressEvent(QMouseEvent* event)
|
void Canvas::mousePressEvent(QMouseEvent* event)
|
||||||
@@ -138,7 +159,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
|
|
||||||
if (!areAlreadyParallel(found, current_line)) {
|
if (!areAlreadyParallel(found, current_line)) {
|
||||||
sys.addConstraintParallel(*found, *current_line, constraints_count++);
|
sys.addConstraintParallel(*found, *current_line, constraints_count++);
|
||||||
parallelPairs.insert(makeOrderedPair(found, current_line));
|
parallelPairs.insert(makeOrderedPair<LinePair>(found, current_line));
|
||||||
current_line = nullptr;
|
current_line = nullptr;
|
||||||
update();
|
update();
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
@@ -164,7 +185,6 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
|
|
||||||
else if (mode == Mode::Coincedent) {
|
else if (mode == Mode::Coincedent) {
|
||||||
Point* clickedPoint = findPointAt(scene);
|
Point* clickedPoint = findPointAt(scene);
|
||||||
|
|
||||||
if (!clickedPoint) {
|
if (!clickedPoint) {
|
||||||
firstPoint = nullptr;
|
firstPoint = nullptr;
|
||||||
update();
|
update();
|
||||||
@@ -189,14 +209,17 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
if (&l->p1 == clickedPoint || &l->p2 == clickedPoint) l2 = l;
|
if (&l->p1 == clickedPoint || &l->p2 == clickedPoint) l2 = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l1 == l2) {
|
if (l1 == l2 ||
|
||||||
|
(areCoincident(firstPoint, clickedPoint, true)))
|
||||||
|
{
|
||||||
QMessageBox::warning(this, QString("NO!"), QString("P2P failed"));
|
QMessageBox::warning(this, QString("NO!"), QString("P2P failed"));
|
||||||
firstPoint = nullptr;
|
firstPoint = nullptr;
|
||||||
update();
|
update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sys.addConstraintP2PCoincident(*firstPoint, *clickedPoint, constraints_count++);
|
sys.addConstraintP2PCoincident(*clickedPoint, *firstPoint, constraints_count++);
|
||||||
|
P2Ppairs.insert(makeOrderedPair<PointPair>(clickedPoint, firstPoint));
|
||||||
firstPoint = nullptr;
|
firstPoint = nullptr;
|
||||||
mode = Mode::None;
|
mode = Mode::None;
|
||||||
after_constraint = true;
|
after_constraint = true;
|
||||||
@@ -313,6 +336,8 @@ Canvas::~Canvas()
|
|||||||
lines.clear();
|
lines.clear();
|
||||||
params.clear();
|
params.clear();
|
||||||
points.clear();
|
points.clear();
|
||||||
|
parallelPairs.clear();
|
||||||
|
P2Ppairs.clear();
|
||||||
|
|
||||||
if (current_line)
|
if (current_line)
|
||||||
delete current_line;
|
delete current_line;
|
||||||
|
|||||||
7
Canvas.h
7
Canvas.h
@@ -24,6 +24,7 @@ enum class Mode : int
|
|||||||
|
|
||||||
// Удобный тип для хранения пары параллельных линий (порядок не важен)
|
// Удобный тип для хранения пары параллельных линий (порядок не важен)
|
||||||
using LinePair = std::pair<Line*, Line*>;
|
using LinePair = std::pair<Line*, Line*>;
|
||||||
|
using PointPair = std::pair<Point*, Point*>;
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
// Основной класс холста
|
// Основной класс холста
|
||||||
@@ -49,9 +50,8 @@ private:
|
|||||||
// ====================== Поиск и выбор ======================
|
// ====================== Поиск и выбор ======================
|
||||||
Line* findAt(QPointF&); // ищет линию под курсором
|
Line* findAt(QPointF&); // ищет линию под курсором
|
||||||
Point* findPointAt(QPointF, qreal tolerance = 10.0);
|
Point* findPointAt(QPointF, qreal tolerance = 10.0);
|
||||||
|
bool areCoincident(Point*, Point*, bool mode = false);
|
||||||
// ====================== Параллельность ======================
|
// ====================== Параллельность ======================
|
||||||
LinePair makeOrderedPair(Line* l1, Line* l2);
|
|
||||||
bool areAlreadyParallel(Line* l1, Line* l2); // проверка на дубликат
|
bool areAlreadyParallel(Line* l1, Line* l2); // проверка на дубликат
|
||||||
|
|
||||||
// ====================== Перемещение ======================
|
// ====================== Перемещение ======================
|
||||||
@@ -65,6 +65,7 @@ private:
|
|||||||
std::vector<double*> params; // все параметры, передаваемые в солвер
|
std::vector<double*> params; // все параметры, передаваемые в солвер
|
||||||
|
|
||||||
std::set<LinePair> parallelPairs; // уже запараллеленные пары (защита от дублей)
|
std::set<LinePair> parallelPairs; // уже запараллеленные пары (защита от дублей)
|
||||||
|
std::set<PointPair> P2Ppairs;
|
||||||
|
|
||||||
Line* current_line{ nullptr };
|
Line* current_line{ nullptr };
|
||||||
Point* firstPoint{ nullptr };
|
Point* firstPoint{ nullptr };
|
||||||
@@ -72,5 +73,5 @@ private:
|
|||||||
bool after_constraint{ false };
|
bool after_constraint{ false };
|
||||||
|
|
||||||
int obj_count{ 0 }; // тег для новых объектов
|
int obj_count{ 0 }; // тег для новых объектов
|
||||||
int constraints_count{ 0 }; // тег для новых ограничений
|
int constraints_count{ 0 }; // тег для новых ограничений
|
||||||
};
|
};
|
||||||
@@ -149,6 +149,11 @@ void Line::set_tag(int _tag) {
|
|||||||
p2.set_tag(_tag);
|
p2.set_tag(_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Line::get_tag()
|
||||||
|
{
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
bool Line::contains(QPointF pos, qreal tol) const
|
bool Line::contains(QPointF pos, qreal tol) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ public:
|
|||||||
void set_tag(int _tag) {
|
void set_tag(int _tag) {
|
||||||
tag = _tag;
|
tag = _tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_tag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using VEC_P = std::vector<Point>;
|
using VEC_P = std::vector<Point>;
|
||||||
@@ -227,6 +231,7 @@ public:
|
|||||||
Line* Copy() override;
|
Line* Copy() override;
|
||||||
|
|
||||||
void set_tag(int);
|
void set_tag(int);
|
||||||
|
int get_tag();
|
||||||
bool contains(QPointF, qreal tol = 10.0) const;
|
bool contains(QPointF, qreal tol = 10.0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user