Отрисовка окружности
This commit is contained in:
223
Canvas.cpp
223
Canvas.cpp
@@ -90,19 +90,13 @@ void Canvas::zoomReset()
|
||||
// Методы поиска и проверки
|
||||
// ===================================================================
|
||||
|
||||
Line* Canvas::findAt(QPointF& pos, qreal tolerance)
|
||||
Curve* Canvas::findAt(QPointF& pos, qreal tolerance)
|
||||
{
|
||||
//for (Curve* curve : curves) {
|
||||
// if (Line* line = dynamic_cast<Line*>(curve)) {
|
||||
// if (line->contains(pos, tolerance)) {
|
||||
// return line;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
for (Line* line : lines) {
|
||||
if (line->contains(pos, tolerance)) {
|
||||
return line;
|
||||
for (Curve* curve : curves) {
|
||||
if (Line* line = dynamic_cast<Line*>(curve)) {
|
||||
if (line->contains(pos, tolerance)) {
|
||||
return line;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -112,26 +106,21 @@ Point* Canvas::findPointAt(QPointF pos, qreal tolerance)
|
||||
{
|
||||
Point* temp = nullptr;
|
||||
|
||||
//for (Curve* curve : curves) {
|
||||
// if (Line* line = dynamic_cast<Line*>(curve)) {
|
||||
// QPointF p1(*line->p1.x, *line->p1.y);
|
||||
// QPointF p2(*line->p2.x, *line->p2.y);
|
||||
for (Curve* curve : curves) {
|
||||
if (Line* line = dynamic_cast<Line*>(curve)) {
|
||||
QPointF p1(*line->p1.x, *line->p1.y);
|
||||
QPointF p2(*line->p2.x, *line->p2.y);
|
||||
|
||||
// if (dist_P2P(p1, pos) <= tolerance)
|
||||
// temp = line->start_ref;
|
||||
// if (dist_P2P(p2, pos) <= tolerance)
|
||||
// temp = line->end_ref;
|
||||
// }
|
||||
//}
|
||||
|
||||
for (Line* line : lines) {
|
||||
QPointF p1(*line->p1.x, *line->p1.y);
|
||||
QPointF p2(*line->p2.x, *line->p2.y);
|
||||
|
||||
if (dist_P2P(p1, pos) <= tolerance)
|
||||
temp = line->start_ref;
|
||||
if (dist_P2P(p2, pos) <= tolerance)
|
||||
temp = line->end_ref;
|
||||
if (dist_P2P(p1, pos) <= tolerance)
|
||||
temp = line->start_ref;
|
||||
if (dist_P2P(p2, pos) <= tolerance)
|
||||
temp = line->end_ref;
|
||||
}
|
||||
else if (Circle* circle = dynamic_cast<Circle*>(curve)) {
|
||||
QPointF center(circle->center.get_X(), circle->center.get_Y());
|
||||
if (dist_P2P(center, pos) <= tolerance)
|
||||
temp = circle->center_ref;
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
@@ -249,7 +238,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
return;
|
||||
}
|
||||
|
||||
Line* found = findAt(scene);
|
||||
Line* found = dynamic_cast<Line*>(findAt(scene));
|
||||
if (found) {
|
||||
draggedLine = found;
|
||||
QPointF lineCenter(
|
||||
@@ -259,11 +248,17 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
dragOffset = scene - lineCenter;
|
||||
return;
|
||||
}
|
||||
|
||||
Circle* found_circle = dynamic_cast<Circle*>(findAt(scene));
|
||||
if (found_circle) {
|
||||
// TODO
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ====================== Режим Horizontal/Vertical ======================
|
||||
else if (mode == Mode::Horizontal || mode == Mode::Vertical) {
|
||||
Line* found = findAt(scene);
|
||||
Line* found = dynamic_cast<Line*>(findAt(scene));
|
||||
|
||||
if (found) {
|
||||
// Проверка: если линия уже вертикальна, нельзя сделать её горизонтальной
|
||||
@@ -370,19 +365,46 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
|
||||
current_line->set_tag(obj_count++);
|
||||
// Завершаем создание линии
|
||||
lines.append(current_line);
|
||||
curves.append(current_line);
|
||||
current_line = nullptr;
|
||||
mode = Mode::None;
|
||||
after_constraint = true;
|
||||
}
|
||||
solve_for_canvas();
|
||||
return;
|
||||
}
|
||||
|
||||
else if (mode == Mode::DrawingCircle) {
|
||||
if (!current_circle) {
|
||||
current_circle = new Circle();
|
||||
// Создаем координаты для центра окружности
|
||||
double* x = new double(scene.x());
|
||||
double* y = new double(scene.y());
|
||||
|
||||
points.push_back(new Point(x, y, obj_count++));
|
||||
|
||||
// Добавляем параметры в солвер
|
||||
params.push_back(x);
|
||||
params.push_back(y);
|
||||
|
||||
current_circle->center.x = x;
|
||||
current_circle->center.y = y;
|
||||
current_circle->center_ref = points[points.size() - 1];
|
||||
}
|
||||
else {
|
||||
double *r = new double(dist_P2P(QPointF(current_circle->center.get_X(), current_circle->center.get_Y()), QPointF(scene.x(), scene.y())));
|
||||
current_circle->rad = r;
|
||||
|
||||
params.push_back(r);
|
||||
curves.append(current_circle);
|
||||
current_circle->set_tag(obj_count++);
|
||||
current_circle = nullptr;
|
||||
mode = Mode::None;
|
||||
}
|
||||
solve_for_canvas();
|
||||
}
|
||||
// ====================== Режим Parallel: задание параллельности ======================
|
||||
else if (mode == Mode::Parallel) {
|
||||
Line* found = findAt(scene);
|
||||
Line* found = dynamic_cast<Line*>(findAt(scene));
|
||||
|
||||
if (!found) {
|
||||
current_line = nullptr;
|
||||
@@ -460,20 +482,13 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
Line* l1 = nullptr;
|
||||
Line* l2 = nullptr;
|
||||
|
||||
//for (Curve* curve : curves) {
|
||||
// if (Line* l = dynamic_cast<Line*>(curve)) {
|
||||
// if (l->start_ref == firstPoint || l->end_ref == firstPoint)
|
||||
// l1 = l;
|
||||
// if (l->start_ref == clickedPoint || l->end_ref == clickedPoint)
|
||||
// l2 = l;
|
||||
// }
|
||||
//}
|
||||
|
||||
for (Line* l : lines) {
|
||||
if (l->start_ref == firstPoint || l->end_ref == firstPoint)
|
||||
l1 = l;
|
||||
if (l->start_ref == clickedPoint || l->end_ref == clickedPoint)
|
||||
l2 = l;
|
||||
for (Curve* curve : curves) {
|
||||
if (Line* l = dynamic_cast<Line*>(curve)) {
|
||||
if (l->start_ref == firstPoint || l->end_ref == firstPoint)
|
||||
l1 = l;
|
||||
if (l->start_ref == clickedPoint || l->end_ref == clickedPoint)
|
||||
l2 = l;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверка на невозможность ограничения
|
||||
@@ -499,7 +514,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
||||
}
|
||||
|
||||
else if (mode == Mode::Perpendicular) {
|
||||
Line* found = findAt(scene);
|
||||
Line* found = dynamic_cast<Line*>(findAt(scene));
|
||||
|
||||
if (!found) {
|
||||
current_line = nullptr;
|
||||
@@ -643,31 +658,40 @@ void Canvas::paintEvent(QPaintEvent* event)
|
||||
|
||||
// ====================== Отрисовка линий ======================
|
||||
|
||||
// for (Curve* curve : curve){
|
||||
// if (Line* line = dynamic_cast<Line*>(curve)) {
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
for (Line* line : lines) {
|
||||
bool isSelected = (mode == Mode::Parallel && line == current_line);
|
||||
for (Curve* curve : curves) {
|
||||
if (Line* line = dynamic_cast<Line*>(curve)) {
|
||||
bool isSelected = (mode == Mode::Parallel && line == current_line);
|
||||
|
||||
// Настройка пера для линии
|
||||
QPen linePen = isSelected ? QPen(Qt::red, 4) : QPen(Qt::black, 2);
|
||||
p.setPen(linePen);
|
||||
// Настройка пера для линии
|
||||
QPen linePen = isSelected ? QPen(Qt::red, 4) : QPen(Qt::black, 2);
|
||||
p.setPen(linePen);
|
||||
|
||||
// Рисуем линию
|
||||
p.drawLine(
|
||||
QPointF(*line->p1.x, *line->p1.y),
|
||||
QPointF(*line->p2.x, *line->p2.y)
|
||||
);
|
||||
// Рисуем линию
|
||||
p.drawLine(
|
||||
QPointF(*line->p1.x, *line->p1.y),
|
||||
QPointF(*line->p2.x, *line->p2.y)
|
||||
);
|
||||
|
||||
// Рисуем конечные точки линии
|
||||
QBrush pointBrush = isSelected ? QBrush(Qt::red) : QBrush(Qt::darkBlue);
|
||||
p.setBrush(pointBrush);
|
||||
p.setPen(Qt::NoPen);
|
||||
// Рисуем конечные точки линии
|
||||
QBrush pointBrush = isSelected ? QBrush(Qt::red) : QBrush(Qt::darkBlue);
|
||||
p.setBrush(pointBrush);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
p.drawEllipse(QPointF(*line->p1.x, *line->p1.y), 5, 5);
|
||||
p.drawEllipse(QPointF(*line->p2.x, *line->p2.y), 5, 5);
|
||||
p.drawEllipse(QPointF(*line->p1.x, *line->p1.y), 5, 5);
|
||||
p.drawEllipse(QPointF(*line->p2.x, *line->p2.y), 5, 5);
|
||||
}
|
||||
else if (Circle* circle = dynamic_cast<Circle*>(curve)) {
|
||||
|
||||
// Настройка пера для линии
|
||||
QPen linePen = QPen(Qt::black, 2);
|
||||
p.setPen(linePen);
|
||||
|
||||
p.drawEllipse(QPointF(*circle->center.x, *circle->center.y), *circle->rad, *circle->rad);
|
||||
QBrush pointBrush = QBrush(Qt::darkBlue);
|
||||
p.setBrush(pointBrush);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(QPointF(*circle->center.x, *circle->center.y), 5, 5);
|
||||
}
|
||||
}
|
||||
|
||||
// ====================== Подсветка выбранной точки (режим Coincedent) ======================
|
||||
@@ -781,19 +805,19 @@ void Canvas::leaveEvent(QEvent* event)
|
||||
#ifdef _DEBUG
|
||||
void Canvas::showObjectTag(QPointF pos)
|
||||
{
|
||||
QPointF l = screenToLogical(pos);
|
||||
Line* lineUnderCursor = findAt(l, 1.0);
|
||||
if (lineUnderCursor && lineUnderCursor != draggedLine) {
|
||||
QPointF p1(*lineUnderCursor->p1.x, *lineUnderCursor->p1.y);
|
||||
QPointF p2(*lineUnderCursor->p2.x, *lineUnderCursor->p2.y);
|
||||
QLineF info_line(p1, p2);
|
||||
QString Text = QString("Line %1\nLength = %2mm")
|
||||
.arg(lineUnderCursor->get_tag() + 1)
|
||||
.arg(info_line.length());
|
||||
QToolTip::showText(mapToGlobal(pos.toPoint()), Text, this);
|
||||
}
|
||||
else
|
||||
QToolTip::hideText();
|
||||
//QPointF l = screenToLogical(pos);
|
||||
//Line* lineUnderCursor = findAt(l, 1.0);
|
||||
//if (lineUnderCursor && lineUnderCursor != draggedLine) {
|
||||
// QPointF p1(*lineUnderCursor->p1.x, *lineUnderCursor->p1.y);
|
||||
// QPointF p2(*lineUnderCursor->p2.x, *lineUnderCursor->p2.y);
|
||||
// QLineF info_line(p1, p2);
|
||||
// QString Text = QString("Line %1\nLength = %2mm")
|
||||
// .arg(lineUnderCursor->get_tag() + 1)
|
||||
// .arg(info_line.length());
|
||||
// QToolTip::showText(mapToGlobal(pos.toPoint()), Text, this);
|
||||
//}
|
||||
//else
|
||||
// QToolTip::hideText();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -841,16 +865,13 @@ void Canvas::solve_for_canvas()
|
||||
}
|
||||
else {
|
||||
sys.applySolution();
|
||||
// for (Curve* curve : curve){
|
||||
// if (Line* line = dynamic_cast<Line*>(curve)) {
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
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;
|
||||
for (Curve* curve : curves) {
|
||||
if (Line* line = dynamic_cast<Line*>(curve)) {
|
||||
if (abs(*line->p1.x - *line->p2.x) < EPS && abs(*line->p1.y - *line->p2.y) < EPS && after_constraint) {
|
||||
sys.undoSolution();
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -885,19 +906,15 @@ void Canvas::clearCanvas()
|
||||
delete pt;
|
||||
}
|
||||
|
||||
// for (Curve* curve : curve){
|
||||
// delete curve;
|
||||
// }
|
||||
|
||||
for (Line* line : lines) {
|
||||
delete line;
|
||||
for (Curve* curve : curves){
|
||||
delete curve;
|
||||
}
|
||||
|
||||
|
||||
// Очистка контейнеров
|
||||
params.clear();
|
||||
points.clear();
|
||||
lines.clear();
|
||||
// curves.clear();
|
||||
curves.clear();
|
||||
|
||||
// Очистка контейнеров ограничений
|
||||
parallelPairs.clear();
|
||||
|
||||
7
Canvas.h
7
Canvas.h
@@ -169,7 +169,7 @@ private:
|
||||
* @param tolerance Допуск поиска
|
||||
* @return Найденная линия или nullptr
|
||||
*/
|
||||
Line* findAt(QPointF& pos, qreal tolerance = 5.0);
|
||||
Curve* findAt(QPointF& pos, qreal tolerance = 5.0);
|
||||
|
||||
/**
|
||||
* @brief Найти точку в указанной позиции
|
||||
@@ -255,9 +255,7 @@ private:
|
||||
|
||||
// ====================== Данные геометрической системы ======================
|
||||
System sys; ///< Геометрический солвер
|
||||
QVector<Line*> lines; ///< Завершённые линии
|
||||
QVector<Circle*> circles; ///< Завершённые окружности
|
||||
QVector<Curve*> curves;
|
||||
QVector<Curve*> curves; ///< Геометрические кривые
|
||||
QVector<Point*> points; ///< Все точки сцены
|
||||
std::vector<double*> params; ///< Все параметры, передаваемые в солвер
|
||||
|
||||
@@ -270,6 +268,7 @@ private:
|
||||
|
||||
// ====================== Временные данные для режимов ======================
|
||||
Line* current_line{ nullptr }; ///< Текущая линия в режимах рисования/параллельности
|
||||
Circle* current_circle{ nullptr };
|
||||
Point* firstPoint{ nullptr }; ///< Первая точка в режиме совпадения
|
||||
Mode mode{ Mode::None }; ///< Текущий режим работы
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ void Line::set_tag(int _tag) {
|
||||
p2.set_tag(_tag);
|
||||
}
|
||||
|
||||
int Line::get_tag()
|
||||
int Curve::get_tag()
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
@@ -275,6 +275,11 @@ Circle* Circle::Copy()
|
||||
return crv;
|
||||
}
|
||||
|
||||
void Circle::set_tag(int _tag) {
|
||||
tag = _tag;
|
||||
center.set_tag(tag);
|
||||
}
|
||||
|
||||
//------------arc
|
||||
int Arc::PushOwnParams(VEC_pD& pvec)
|
||||
{
|
||||
|
||||
10
GCS/Geo.h
10
GCS/Geo.h
@@ -173,6 +173,8 @@ public:
|
||||
/// A base class for all curve-based objects (line, circle/arc, ellipse/arc).
|
||||
class Curve
|
||||
{
|
||||
protected:
|
||||
int tag;
|
||||
public:
|
||||
virtual ~Curve()
|
||||
{}
|
||||
@@ -212,12 +214,13 @@ public:
|
||||
// DeepSOIC: I haven't found a way to simply copy a curve object provided pointer to a curve
|
||||
// object.
|
||||
virtual Curve* Copy() = 0;
|
||||
|
||||
void set_tag(int);
|
||||
int get_tag();
|
||||
};
|
||||
|
||||
class Line: public Curve
|
||||
{
|
||||
private:
|
||||
int tag;
|
||||
public:
|
||||
Line()
|
||||
{}
|
||||
@@ -238,7 +241,6 @@ public:
|
||||
Line* Copy() override;
|
||||
|
||||
void set_tag(int);
|
||||
int get_tag();
|
||||
bool contains(QPointF, qreal tol) const;
|
||||
|
||||
};
|
||||
@@ -253,12 +255,14 @@ public:
|
||||
~Circle() override
|
||||
{}
|
||||
Point center;
|
||||
Point* center_ref;
|
||||
double* rad;
|
||||
DeriVector2 CalculateNormal(const Point& p, const double* derivparam = nullptr) const override;
|
||||
DeriVector2 Value(double u, double du, const double* derivparam = nullptr) const override;
|
||||
int PushOwnParams(VEC_pD& pvec) override;
|
||||
void ReconstructOnNewPvec(VEC_pD& pvec, int& cnt) override;
|
||||
Circle* Copy() override;
|
||||
void set_tag(int);
|
||||
};
|
||||
|
||||
class Arc: public Circle
|
||||
|
||||
Reference in New Issue
Block a user