Форматирование под doxygen

This commit is contained in:
2025-12-22 23:21:22 +03:00
parent 1a2a7e1cbc
commit 1cbbaef68b
2 changed files with 200 additions and 51 deletions

View File

@@ -8,13 +8,30 @@ std::set<Point*> groups;
// Вспомогательные функции // Вспомогательные функции
// =================================================================== // ===================================================================
/// Вычислить расстояние между двумя точками /**
* @brief Вычислить расстояние между двумя точками
* @param p1 Первая точка
* @param p2 Вторая точка
* @return Расстояние между точками
*/
static double dist_P2P(QPointF p1, QPointF p2) static double dist_P2P(QPointF p1, QPointF p2)
{ {
return sqrt(pow(p2.x() - p1.x(), 2) + pow(p2.y() - p1.y(), 2)); return sqrt(pow(p2.x() - p1.x(), 2) + pow(p2.y() - p1.y(), 2));
} }
/// Создать упорядоченную пару (чтобы pair(obj1, obj2) и pair(obj2, obj1) считались одинаковыми) /**
* @brief Создать упорядоченную пару
*
* Создает пару, в которой элементы упорядочены по указателям,
* чтобы pair(obj1, obj2) и pair(obj2, obj1) считались одинаковыми
*
* @tparam T Тип возвращаемой пары
* @tparam A Тип первого элемента
* @tparam B Тип второго элемента
* @param obj1 Первый объект
* @param obj2 Второй объект
* @return Упорядоченная пара
*/
template <typename T, typename A, typename B> template <typename T, typename A, typename B>
T makeOrderedPair(A* obj1, B* obj2) T makeOrderedPair(A* obj1, B* obj2)
{ {
@@ -41,7 +58,7 @@ Canvas::~Canvas()
} }
// =================================================================== // ===================================================================
// Методы изменения режима // Методы изменения режима и масштаба
// =================================================================== // ===================================================================
void Canvas::changeMode(Mode _mode) void Canvas::changeMode(Mode _mode)
@@ -141,7 +158,6 @@ bool Canvas::areAlreadyPerpendicular(Line* line1, Line* line2)
// Методы работы с ограничениями // Методы работы с ограничениями
// =================================================================== // ===================================================================
// TODO - переделать в bool для отображения статуса выполнения
void Canvas::remove_constraint(int tag) void Canvas::remove_constraint(int tag)
{ {
auto it = C_Info.find(tag); auto it = C_Info.find(tag);
@@ -380,9 +396,9 @@ void Canvas::mousePressEvent(QMouseEvent* event)
} }
else { else {
// Линии уже параллельны - сообщаем об ошибке // Линии уже параллельны - сообщаем об ошибке
#ifdef _DEBUG #ifdef _DEBUG
qDebug() << "Line" << current_line << "and" << found << "are parallel. Abort!"; qDebug() << "Line" << current_line << "and" << found << "are parallel. Abort!";
#endif #endif
QMessageBox::warning(this, QMessageBox::warning(this,
QString("Wrong"), QString("Wrong"),
@@ -553,10 +569,10 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
} }
solve_for_canvas(); solve_for_canvas();
} }
#ifdef _DEBUG #ifdef _DEBUG
else else
showObjectTag(WIDGET_POSITION); showObjectTag(WIDGET_POSITION);
#endif #endif
} }
void Canvas::mouseReleaseEvent(QMouseEvent* event) void Canvas::mouseReleaseEvent(QMouseEvent* event)
@@ -637,6 +653,10 @@ void Canvas::paintEvent(QPaintEvent* event)
} }
} }
// ===================================================================
// Обработчики событий клавиатуры и колесика мыши
// ===================================================================
void Canvas::keyPressEvent(QKeyEvent* event) void Canvas::keyPressEvent(QKeyEvent* event)
{ {
switch (event->key()) { switch (event->key()) {
@@ -734,11 +754,15 @@ void Canvas::showObjectTag(QPointF pos)
.arg(info_line.length()); .arg(info_line.length());
QToolTip::showText(mapToGlobal(pos.toPoint()), Text, this); QToolTip::showText(mapToGlobal(pos.toPoint()), Text, this);
} }
else else
QToolTip::hideText(); QToolTip::hideText();
} }
#endif #endif
// ===================================================================
// Вспомогательные методы
// ===================================================================
QPointF Canvas::screenToLogical(const QPointF& screenPos) const QPointF Canvas::screenToLogical(const QPointF& screenPos) const
{ {
QPointF logical = screenPos; QPointF logical = screenPos;
@@ -787,13 +811,13 @@ void Canvas::solve_for_canvas()
} }
} }
} }
if (flag) { if (flag) {
QMessageBox::warning(this, QString("Error!"), QString("Last constraint is unavailable!")); QMessageBox::warning(this, QString("Error!"), QString("Last constraint is unavailable!"));
remove_constraint(constraints_count - 1); remove_constraint(constraints_count - 1);
C_Info.erase(constraints_count - 1); C_Info.erase(constraints_count - 1);
constraints_count--; constraints_count--;
} }
after_constraint = false; after_constraint = false;
update(); update();
} }

199
Canvas.h
View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
constexpr auto EPS = 1e-9; constexpr auto EPS = 1e-9;
constexpr auto ZOOM_STEP = 0.05; constexpr auto ZOOM_STEP = 0.05;
@@ -22,7 +23,9 @@ using namespace GCS;
// Типы и перечисления // Типы и перечисления
// =================================================================== // ===================================================================
/// Режимы работы с холстом /**
* @brief Режимы работы с холстом
*/
enum class Mode : int enum class Mode : int
{ {
None = 0, ///< Режим отсутствия действия None = 0, ///< Режим отсутствия действия
@@ -30,8 +33,8 @@ enum class Mode : int
Parallel = 2, ///< Режим задания параллельности Parallel = 2, ///< Режим задания параллельности
Coincedent = 3, ///< Режим задания совпадения точек Coincedent = 3, ///< Режим задания совпадения точек
Horizontal = 4, ///< Режим задания горизонтальности Horizontal = 4, ///< Режим задания горизонтальности
Vertical = 5, ///< Режим задания вертикальности Vertical = 5, ///< Режим задания вертикальности
Perpendicular = 6 Perpendicular = 6 ///< Режим задания перпендикулярности
}; };
/// Удобный тип для хранения пары параллельных линий (порядок не важен) /// Удобный тип для хранения пары параллельных линий (порядок не важен)
@@ -44,123 +47,245 @@ using PointPair = std::pair<Point*, Point*>;
// Основной класс холста // Основной класс холста
// =================================================================== // ===================================================================
/**
* @brief Класс холста для рисования геометрических фигур с ограничениями
*
* Класс предоставляет функциональность для создания и редактирования
* геометрических объектов с применением ограничений через геометрический
* солвер FreeCAD GCS.
*/
class Canvas : public QWidget class Canvas : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
/**
* @brief Конструктор класса Canvas
* @param parent Родительский виджет
*/
explicit Canvas(QWidget* parent = nullptr); explicit Canvas(QWidget* parent = nullptr);
/**
* @brief Деструктор класса Canvas
*/
~Canvas() override; ~Canvas() override;
/// Изменить текущий режим работы /**
* @brief Изменить текущий режим работы
* @param newMode Новый режим работы
*/
void changeMode(Mode newMode); void changeMode(Mode newMode);
/// Увеличить масштаб /**
* @brief Увеличить масштаб
*
* Увеличивает масштаб отображения на 5%
*/
void zoomIn(); void zoomIn();
/// Уменьшить масштаб /**
* @brief Уменьшить масштаб
*
* Уменьшает масштаб отображения на 5%
*/
void zoomOut(); void zoomOut();
/// Сбросить масштаб к 100% /**
* @brief Сбросить масштаб к 100%
*/
void zoomReset(); void zoomReset();
protected: protected:
// Обработчики событий Qt /**
* @brief Обработчик нажатия кнопки мыши
* @param event Событие мыши
*/
void mousePressEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override;
/**
* @brief Обработчик перемещения мыши
* @param event Событие мыши
*/
void mouseMoveEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override;
/**
* @brief Обработчик отпускания кнопки мыши
* @param event Событие мыши
*/
void mouseReleaseEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override;
/**
* @brief Обработчик вращения колесика мыши
* @param event Событие колесика мыши
*/
void wheelEvent(QWheelEvent* event) override; void wheelEvent(QWheelEvent* event) override;
/**
* @brief Обработчик события отрисовки
* @param event Событие отрисовки
*/
void paintEvent(QPaintEvent* event) override; void paintEvent(QPaintEvent* event) override;
void keyPressEvent(QKeyEvent* event);
/**
* @brief Обработчик нажатия клавиши клавиатуры
* @param event Событие клавиатуры
*/
void keyPressEvent(QKeyEvent* event) override;
/**
* @brief Обработчик выхода курсора за пределы виджета
* @param event Событие
*/
void leaveEvent(QEvent* event) override; void leaveEvent(QEvent* event) override;
private: private:
#ifdef _DEBUG #ifdef _DEBUG
/**
* @brief Показать тег объекта под курсором (только в режиме отладки)
* @param pos Позиция курсора на экране
*/
void showObjectTag(QPointF pos); void showObjectTag(QPointF pos);
#endif #endif
/**
* @brief Преобразовать координаты экрана в логические координаты
* @param screenPos Координаты на экране
* @return Логические координаты
*/
QPointF screenToLogical(const QPointF& screenPos) const; QPointF screenToLogical(const QPointF& screenPos) const;
/**
* @brief Получить группу совпадающих точек
* @param p Базовая точка
*/
void getCoincidentGroup(Point* p); void getCoincidentGroup(Point* p);
// ====================== Методы поиска и выбора ====================== // ====================== Методы поиска и выбора ======================
/// Найти линию под указанной позицией /**
* @brief Найти линию под указанной позицией
* @param pos Позиция для поиска
* @param tolerance Допуск поиска
* @return Найденная линия или nullptr
*/
Line* findAt(QPointF& pos, qreal tolerance = 5.0); Line* findAt(QPointF& pos, qreal tolerance = 5.0);
/// Найти точку в указанной позиции с заданной точностью /**
* @brief Найти точку в указанной позиции
* @param position Позиция для поиска
* @param tolerance Допуск поиска
* @return Найденная точка или nullptr
*/
Point* findPointAt(QPointF position, qreal tolerance = 5.0); Point* findPointAt(QPointF position, qreal tolerance = 5.0);
/// Проверить, совпадают ли две точки (ограничение P2P) /**
* @brief Проверить, совпадают ли две точки (ограничение P2P)
* @param point1 Первая точка
* @param point2 Вторая точка
* @return true если точки совпадают, иначе false
*/
bool areCoincident(Point* point1, Point* point2); bool areCoincident(Point* point1, Point* point2);
/// Проверить горизонтальность или вертикальность между двумя точками /**
/// @param mode: false - горизонтальность, true - вертикальность * @brief Проверить горизонтальность или вертикальность между двумя точками
* @param point1 Первая точка
* @param point2 Вторая точка
* @param mode false - проверка горизонтальности, true - проверка вертикальности
* @return true если точки имеют указанное ограничение, иначе false
*/
bool areHorizontalVertical(Point* point1, Point* point2, bool mode); bool areHorizontalVertical(Point* point1, Point* point2, bool mode);
/// Проверить, является ли линия горизонтальной /**
* @brief Проверить, является ли линия горизонтальной
* @param line Линия для проверки
* @return true если линия горизонтальна, иначе false
*/
bool isLineHorizontal(Line* line); bool isLineHorizontal(Line* line);
/// Проверить, является ли линия вертикальной /**
* @brief Проверить, является ли линия вертикальной
* @param line Линия для проверки
* @return true если линия вертикальна, иначе false
*/
bool isLineVertical(Line* line); bool isLineVertical(Line* line);
/// Проверить, являются ли две линии уже параллельными (дубликат ограничения) /**
* @brief Проверить, являются ли две линии уже параллельными
* @param line1 Первая линия
* @param line2 Вторая линия
* @return true если линии уже параллельны, иначе false
*/
bool areAlreadyParallel(Line* line1, Line* line2); bool areAlreadyParallel(Line* line1, Line* line2);
/**
* @brief Проверить, являются ли две линии уже перпендикулярными
* @param line1 Первая линия
* @param line2 Вторая линия
* @return true если линии уже перпендикулярны, иначе false
*/
bool areAlreadyPerpendicular(Line* line1, Line* line2); bool areAlreadyPerpendicular(Line* line1, Line* line2);
// ====================== Методы работы с ограничениями ====================== // ====================== Методы работы с ограничениями ======================
/// Удалить последние добавленные ограничения при ошибке солвера /**
void remove_constraint(int); * @brief Удалить ограничение по его тегу
* @param tag Тег ограничения
*/
void remove_constraint(int tag);
/**
* @brief Решить геометрическую систему
*
* Вызывает солвер для решения системы ограничений и обновляет отображение
*/
void solve_for_canvas();
/**
* @brief Очистить холст
*
* Удаляет все объекты и ограничения, сбрасывает состояние
*/
void clearCanvas();
// ====================== Данные для перемещения объектов ====================== // ====================== Данные для перемещения объектов ======================
Point* draggedPoint{ nullptr }; ///< Точка, которую перемещают Point* draggedPoint{ nullptr }; ///< Точка, которую перемещают
Line* draggedLine{ nullptr }; ///< Линия, которую перемещают Line* draggedLine{ nullptr }; ///< Линия, которую перемещают
QPointF dragOffset; ///< Смещение при начале перемещения QPointF dragOffset; ///< Смещение при начале перемещения
// ====================== Данные геометрической системы ====================== // ====================== Данные геометрической системы ======================
System sys; ///< Геометрический солвер System sys; ///< Геометрический солвер
QVector<Line*> lines; ///< Завершённые линии QVector<Line*> lines; ///< Завершённые линии
QVector<Point*> points; ///< Все точки сцены QVector<Point*> points; ///< Все точки сцены
std::vector<double*> params; ///< Все параметры, передаваемые в солвер std::vector<double*> params; ///< Все параметры, передаваемые в солвер
// ====================== Коллекции ограничений ====================== // ====================== Коллекции ограничений ======================
std::set<LinePair> parallelPairs; ///< Пары параллельных линий std::set<LinePair> parallelPairs; ///< Пары параллельных линий
std::set<LinePair> perpendicularPairs; std::set<LinePair> perpendicularPairs; ///< Пары перпендикулярных линий
std::set<PointPair> P2Ppairs; ///< Пары совпадающих точек std::set<PointPair> P2Ppairs; ///< Пары совпадающих точек
std::set<PointPair> HORIZ_pairs; ///< Пары точек горизонтальных линий std::set<PointPair> HORIZ_pairs; ///< Пары точек горизонтальных линий
std::set<PointPair> VERT_pairs; ///< Пары точек вертикальных линий std::set<PointPair> VERT_pairs; ///< Пары точек вертикальных линий
// ====================== Временные данные для режимов ====================== // ====================== Временные данные для режимов ======================
Line* current_line{ nullptr }; ///< Текущая линия в режимах рисования/параллельности Line* current_line{ nullptr }; ///< Текущая линия в режимах рисования/параллельности
Point* firstPoint{ nullptr }; ///< Первая точка в режиме совпадения Point* firstPoint{ nullptr }; ///< Первая точка в режиме совпадения
Mode mode{ Mode::None }; ///< Текущий режим работы Mode mode{ Mode::None }; ///< Текущий режим работы
// ====================== Флаги состояния ====================== // ====================== Флаги состояния ======================
bool after_constraint{ false }; ///< Флаг, что только что добавлено ограничение bool after_constraint{ false }; ///< Флаг, что только что добавлено ограничение
double scaleFactor { 1.0 }; double scaleFactor{ 1.0 }; ///< Текущий масштаб отображения (1.0 = 100%)
// ====================== Счётчики ====================== // ====================== Счётчики ======================
int obj_count{ 0 }; ///< Счётчик объектов (для тегов) int obj_count{ 0 }; ///< Счётчик объектов (для тегов)
int constraints_count{ 0 }; ///< Счётчик ограничений (для тегов) int constraints_count{ 0 }; ///< Счётчик ограничений (для тегов)
// ====================== Информация о последнем ограничении ====================== // ====================== Информация о последнем ограничении ======================
/**
/// Структура для хранения информации о последнем добавленном ограничении * @brief Структура для хранения информации об ограничении
/// (используется для отката при ошибке солвера) */
struct ConstraintInfo { struct ConstraintInfo {
Mode mode; Mode mode; ///< Тип ограничения
std::variant<LinePair, PointPair> data; std::variant<LinePair, PointPair> data; ///< Данные ограничения
}; };
std::map<int, ConstraintInfo> C_Info;
void solve_for_canvas(); std::map<int, ConstraintInfo> C_Info; ///< Карта информации об ограничениях
void clearCanvas();
}; };