Make parallel lines

And make TODO for P2P
This commit is contained in:
ParkSuMin
2025-12-07 15:54:59 +03:00
parent 94761fecbc
commit 5c0e04df5b
7 changed files with 199 additions and 39 deletions

View File

@@ -1,21 +1,43 @@
#include "Canvas.h"
void Canvas::changeMode(Mode _mode)
{
mode = _mode;
}
// TODO
Line* Canvas::findAt(QPointF& pos)
{
for (Line* line : lines) {
if (line->contains(pos)) {
return line;
}
}
return nullptr;
}
LinePair Canvas::makeOrderedPair(Line* l1, Line* l2)
{
return (l1 < l2) ? std::make_pair(l1, l2) : std::make_pair(l2, l1);
}
bool Canvas::areAlreadyParallel(Line* l1, Line* l2)
{
return parallelPairs.count(makeOrderedPair(l1, l2)) > 0;
}
void Canvas::mousePressEvent(QMouseEvent* event)
{
QPointF scene = event->pos();
#ifdef _DEBUG
qDebug() << "Scene point in" << scene.x() << scene.y();
changeMode(DrawingLine);
#endif
if (mode == DrawingLine) {
if (mode == Mode::DrawingLine) {
if (!current_line) {
current_line = new Line();
current_line->set_tag(obj_count);
double* x1 = new double(scene.x());
double* y1 = new double(scene.y());
@@ -25,6 +47,9 @@ void Canvas::mousePressEvent(QMouseEvent* event)
params.push_back(x1);
params.push_back(y1);
points.push_back(Point(x1, y1, obj_count));
points.push_back(Point(x2, y2, obj_count));
current_line->p1.x = x1;
current_line->p1.y = y1;
current_line->p2.x = x2;
@@ -39,25 +64,83 @@ void Canvas::mousePressEvent(QMouseEvent* event)
lines.append(current_line);
current_line = nullptr;
mode = Mode::None;
obj_count++;
update();
return;
}
}
//#ifdef _DEBUG
// if (lines.size()) {
// qDebug() << "Line coords" << lines[lines.size() - 1]->p1.get_X() <<
// lines[lines.size() - 1]->p1.get_Y() <<
// lines[lines.size() - 1]->p2.get_X() <<
// lines[lines.size() - 1]->p2.get_Y();
// changeMode(None);
// }
//#endif
else if (mode == Mode::Parallel) {
static Line* first = nullptr;
Line* found = findAt(scene);
if (!found) {
first = nullptr;
return;
}
if (!first) {
first = found;
return;
}
if (found == first){
first = nullptr;
return;
}
if (!areAlreadyParallel(found, first)) {
sys.addConstraintParallel(*found, *first, constraints_count++);
parallelPairs.insert(makeOrderedPair(found, first));
first = nullptr;
mode = Mode::None;
}
else {
#ifdef _DEBUG
qDebug() << "Line" << first << "and" << found << "are parallel. Abort!";
#endif
QMessageBox::information(this,
QString("Wrong"),
QString("Parallel lines can not be more parallel!"),
QMessageBox::Ok
);
first = nullptr;
return;
}
update();
}
}
void Canvas::paintEvent(QPaintEvent*)
{
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
if (!params.empty()) {
int res = sys.solve(params);
if (res == SolveStatus::Success) {
sys.applySolution();
}
else {
#ifdef _DEBUG
qDebug() << "INVAILD LAST CONSTRAINT. REMOVE HIM";
#endif
sys.removeConstraint(sys.get_last_constraint());
}
}
for (Line* line : lines) {
line->draw(p);
}
return;
}
Canvas::Canvas(QWidget *parent)
: QWidget(parent)
{
sys = System();
current_line = nullptr;
setMouseTracking(true);
setBackgroundRole(QPalette::Base);
@@ -76,6 +159,7 @@ Canvas::~Canvas()
lines.clear();
params.clear();
points.clear();
if (current_line)
delete current_line;

View File

@@ -2,33 +2,65 @@
#include <QWidget>
#include <QMouseEvent>
#include <QPointF>
#include <QMessageBox>
#ifdef _DEBUG
#include <QDebug>
#endif
// GCS — ãåîìåòðè÷åñêèé ñîëâåð èç FreeCAD
#include "GCS/Geo.h"
#include "GCS/GCS.h"
using namespace GCS;
enum Mode {
None,
DrawingLine
enum class Mode : int
{
None = 0,
DrawingLine = 1,
Parallel = 2
};
// Óäîáíûé òèï äëÿ õðàíåíèÿ ïàðû ïàðàëëåëüíûõ ëèíèé (ïîðÿäîê íå âàæåí)
using LinePair = std::pair<Line*, Line*>;
// ===================================================================
// Îñíîâíîé êëàññ õîëñòà
// ===================================================================
class Canvas : public QWidget
{
Q_OBJECT
private:
void changeMode(Mode);
Mode mode = Mode::None;
QVector<Line*> lines;
QVector<Point> points;
QVector<double*> params;
Line* current_line;
protected:
void mousePressEvent(QMouseEvent*) override;
public:
Canvas(QWidget *parent);
~Canvas();
};
public:
explicit Canvas(QWidget* parent = nullptr);
~Canvas() override;
void changeMode(Mode newMode);
protected:
void mousePressEvent(QMouseEvent* event) override;
void paintEvent(QPaintEvent* event) override;
private:
// ====================== Ïîèñê è âûáîð ======================
Line* findAt(QPointF&); // èùåò ëèíèþ ïîä êóðñîðîì
// ====================== Ïàðàëëåëüíîñòü ======================
LinePair makeOrderedPair(Line* l1, Line* l2);
bool areAlreadyParallel(Line* l1, Line* l2); // ïðîâåðêà íà äóáëèêàò
// ====================== Äàííûå ñöåíû ======================
System sys; // ãåîìåòðè÷åñêèé ñîëâåð
QVector<Line*> lines; // çàâåðø¸ííûå ëèíèè
QVector<Point> points; // âñå òî÷êè (äëÿ óäîáíîãî äîñòóïà)
std::vector<double*> params; // âñå ïàðàìåòðû, ïåðåäàâàåìûå â ñîëâåð
std::set<LinePair> parallelPairs; // óæå çàïàðàëëåëåííûå ïàðû (çàùèòà îò äóáëåé)
Line* current_line{ nullptr };
Mode mode{ Mode::None };
int obj_count{ 0 }; // òåã äëÿ íîâûõ îáúåêòîâ
int constraints_count{ 0 }; // òåã äëÿ íîâûõ îãðàíè÷åíèé
};

View File

@@ -14,5 +14,18 @@ DRAWer_2_0::~DRAWer_2_0()
void DRAWer_2_0::on_pushButton_clicked()
{
ui.label->setText(QString::number(counter++));
ui.widget->changeMode(Mode::DrawingLine);
}
void DRAWer_2_0::on_pushButton_2_clicked()
{
ui.widget->changeMode(Mode::Parallel);
}
void DRAWer_2_0::on_pushButton_3_clicked()
{
return;
}

View File

@@ -14,6 +14,10 @@ public:
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::DRAWer_2_0Class ui;
int counter;

View File

@@ -250,6 +250,9 @@ public:
void clearByTag(int tagId, bool is_fixed_point = false);
int addConstraint(Constraint* constr);
void removeConstraint(Constraint* constr);
Constraint* get_last_constraint() {
return clist[clist.size() - 1];
}
// basic constraints
int addConstraintFixed(Point& p, int tagId = 0, bool driving = true);

View File

@@ -143,6 +143,33 @@ Line::Line(Point _p1, Point _p2, int _tag) {
tag = _tag;
}
void Line::set_tag(int _tag) {
tag = _tag;
p1.set_tag(_tag);
p2.set_tag(_tag);
}
// TODO
bool Line::contains(QPointF pos, qreal tol) const
{
double x1 = *p1.x, y1 = *p1.y;
double x2 = *p2.x, y2 = *p2.y;
double A = y1 - y2;
double B = x2 - x1;
double C = x1 * y2 - x2 * y1;
try {
double distance = abs(A * pos.x() + B * pos.y() + C) / sqrt(A * A + B * B);
return distance < tol;
}
catch (...) {
return false;
}
}
DeriVector2 Line::CalculateNormal(const Point& p, const double* derivparam) const
{
(void)p;

View File

@@ -227,11 +227,8 @@ public:
Line* Copy() override;
void draw(QPainter& p, bool highlight = false);
void set_tag(int _tag) {
tag = _tag;
p1.set_tag(_tag);
p2.set_tag(_tag);
}
void set_tag(int);
bool contains(QPointF, qreal tol = 10.0) const;
};
class Circle: public Curve