KanoopCommonQt 2.1.1
Kanoop foundational Qt utility library
Loading...
Searching...
No Matches
pathrouter.h
1#ifndef PATHROUTER_H
2#define PATHROUTER_H
3
4#include "line.h"
5
6#include <QList>
7#include <QRect>
8#include <QString>
9
10#include "point.h"
11#include "rectangle.h"
12#include "Kanoop/kanoopcommon.h"
13
14/**
15 * @brief Orthogonal path-routing algorithm that navigates around rectangular obstacles.
16 *
17 * PathRouter computes a list of horizontal/vertical line segments connecting an origin
18 * point to a destination point while avoiding a set of rectangular obstacles on a canvas.
19 * Call calcluatePath() after configuration to obtain the routed Line::List.
20 */
21class KANOOP_EXPORT PathRouter
22{
23public:
24 /** @brief Default constructor — creates an unconfigured router with default margin settings. */
26 _direction(Geo::NoDirection),
27 _forceDirection(Geo::NoDirection),
28 _initialDirectionForced(false),
29 _firstSegmentLength(0),
30 _complete(false),
31 _routingMargin(DefaultRoutingMargin),
32 _consolidateEmptyRectangles(true),
33 _routeAroundMargins(true),
34 _verticalConstraint(-1),
35 _debugLevel(0) {}
36
37 /**
38 * @brief Construct a PathRouter with full configuration.
39 * @param origin Starting point for the path
40 * @param destination Ending point for the path
41 * @param canvas Bounding rectangle for the entire routing area
42 * @param obstacles List of rectangular obstacles to route around (default empty)
43 */
44 PathRouter(const Point& origin, const Point& destination, const QRectF &canvas, const QList<Rectangle> &obstacles = QList<Rectangle>());
45
46 /**
47 * @brief Compute the routed path from origin to destination avoiding all obstacles.
48 * @return Ordered list of line segments forming the routed path
49 */
51
52 /**
53 * @brief Append a single obstacle rectangle to the routing obstacle set.
54 * @param value Obstacle rectangle to add
55 */
56 void appendObstacle(const Rectangle& value) { _obstacles.append(value); }
57
58 /**
59 * @brief Replace the entire obstacle set.
60 * @param value New list of obstacle rectangles
61 */
62 void setObstacles(const QList<Rectangle>& value) { _obstacles = value; }
63
64 /**
65 * @brief Return the origin point.
66 * @return Current origin Point
67 */
68 Point originPoint() const { return _originPoint; }
69
70 /**
71 * @brief Set the origin point.
72 * @param value New origin Point
73 */
74 void setOriginPoint(const Point& value) { _originPoint = value ; }
75
76 /**
77 * @brief Return the destination point.
78 * @return Current destination Point
79 */
80 Point destinationPoint() const { return _destinationPoint; }
81
82 /**
83 * @brief Set the destination point.
84 * @param value New destination Point
85 */
86 void setDestinationPoint(const Point& value) { _destinationPoint = value; }
87
88 /**
89 * @brief Return the routing margin applied around each obstacle.
90 * @return Margin in pixels/units
91 */
92 int routingMargin() const { return _routingMargin; }
93
94 /**
95 * @brief Set the routing margin applied around each obstacle.
96 * @param value Margin in pixels/units
97 */
98 void setRoutingMargin(int value) { _routingMargin = value; }
99
100 /**
101 * @brief Return whether empty (non-obstacle) rectangles are consolidated before routing.
102 * @return true if consolidation is enabled
103 */
104 bool consolidateEmptyRectangles() const { return _consolidateEmptyRectangles; }
105
106 /**
107 * @brief Enable or disable consolidation of empty rectangles before routing.
108 * @param value true to enable consolidation
109 */
110 void setConsolidateEmptyRectangles(bool value) { _consolidateEmptyRectangles = value; }
111
112 /**
113 * @brief Return whether the router routes around obstacle margins.
114 * @return true if margin-based routing is enabled
115 */
116 bool routeAroundMargins() const { return _routeAroundMargins; }
117
118 /**
119 * @brief Enable or disable routing around obstacle margins.
120 * @param value true to route around margins
121 */
122 void setRouteAroundMargins(bool value) { _routeAroundMargins = value; }
123
124 /**
125 * @brief Force the direction of the first routed segment.
126 * @param direction Preferred initial travel direction
127 */
128 void setInitialDirection(Geo::Direction direction) { _forceDirection = direction; }
129
130 /**
131 * @brief Set the length of the first segment before obstacle avoidance begins.
132 * @param value Length in pixels/units
133 */
134 void setFirstSegmentLength(double value) { _firstSegmentLength = value; }
135
136 /**
137 * @brief Return the vertical constraint (maximum Y coordinate the path may reach).
138 * @return Constraint Y value, or -1 if unconstrained
139 */
140 int verticalConstraint() const { return _verticalConstraint; }
141
142 /**
143 * @brief Set the vertical constraint (maximum Y the path may reach).
144 * @param value Y constraint value, or -1 to disable
145 */
146 void setVerticalConstraint(int value) { _verticalConstraint = value; }
147
148 /**
149 * @brief Return the debug verbosity level.
150 * @return Debug level (0 = silent)
151 */
152 int debugLevel() const { return _debugLevel; }
153
154 /**
155 * @brief Set the debug verbosity level.
156 * @param value Debug level (0 = silent, higher = more verbose)
157 */
158 void setDebugLevel(int value) { _debugLevel = value; }
159
160 /**
161 * @brief Merge adjacent collinear line segments in-place.
162 * @param lines Line list to process; merged in place
163 */
164 static void mergeAdjacentLines(Line::List& lines);
165
166private:
167 bool pass1();
168 bool pass2();
169 bool pass3();
170 bool cycleOnPass1(const Point& a, const Point& b);
171 bool cycleFindDirectShot(const Point& a, const Point& b);
172 bool cycleChooseDirection(const Point& a, const Point& b);
173 bool cycleSimpleLShot(const Point &a, const Point &b);
174 bool cycleFindWayOffObstacle(const Point& a, const Point& b);
175 bool cycleFindNextPoint(const Point& a, const Point& b);
176
177 bool rectangleCrossesObstacle(const Rectangle &rectangle, const QList<Rectangle> &ignoreObstacles = QList<Rectangle>()) const;
178 bool linesCrossObstacle(const Line::List &lines) const;
179 bool lineCrossesObstacle(const Line &line) const;
180 bool lineCrossesObstacle(const Line &line, Rectangle &firstObstacle, Point &intersection) const;
181 bool lineCrossesObstacle(const Line &line, const Rectangle &ignoreObstacle, Rectangle &firstObstacle, Point &intersection) const;
182 bool lineCrossesObstacle(const Line &line, const QList<Rectangle> &ignoreObstacles, Rectangle &firstObstacle, Point &intersection) const;
183 bool pointLiesWithinObstacle(const Point &point, Rectangle &result);
184 bool pointLiesOnObstacleEdge(const Point &point, Rectangle &result);
185 bool pointLiesOnObstacleEdge(const Point &point, Rectangle &result, Line& foundEdge);
186 bool lineLiesOnObstacleEdge(const Line &line, Rectangle &foundObstacle, Line& foundEdge);
187 bool lineLiesNearObstacleEdge(const Line &line, double margin, Rectangle &foundObstacle, Line& foundEdge);
188 void replaceLines(int index, int count, const Line::List &newLines);
189 Geo::Direction directionOffObstacle(const Line& line, const Rectangle& obstacle);
190
191 static QList<Geo::Direction> chooseDirections(const Point& a, const Point& b);
192 static Geo::Direction chooseDirection(const Point& a, const Point& b, Geo::Direction exclude = Geo::NoDirection);
193 static Geo::Direction chooseDirection(const Point& a, const Point& b, const QList<Geo::Direction> exclude);
194 static Geo::Direction nonExcludedDirection(QList<Geo::Direction> choices, QList<Geo::Direction> exclude);
195 static Geo::Direction directionOfLine(const Line& line);
196
197 Rectangle makeRectangleFromThreeLines(const Line::List &lines, Line &newLine) const;
198
199 Line rayInDirection(const Point& origin, Geo::Direction direction) const;
200 Line seekClearLine(const Point& origin, Geo::Direction moveAxis, Geo::Direction seekAxis, double distanceLimit = 0);
201 Line reduceLineToTarget(const Line& line, Geo::Direction direction, const Point& target, double margin);
202 double distanceInDirection(const Point& origin, Geo::Direction direction, const Point& target) const;
203 Line findClosestCornerPathOffObstacle(const Point& origin, const Rectangle &obstacle, Geo::Direction& resultDirection) const;
204 Line findPathOffObstacleInDirections(const Point& origin, const Rectangle &obstacle, const QList<Geo::Direction>& directions) const;
205 bool pointLiesOnAppropriateObtstacleCorner(const Point& origin, const Rectangle &obstacle, const QList<Geo::Direction>& directions) const;
206 Geo::Direction lastLineDirection() const;
207 void removeZeroLengthLines(Line::List& lines) const;
208 void mergeTinySegments(Line::List& lines) const;
209 bool lineCrossesVerticalConstraint(const Line& line);
210 static int countAdjacentLines(const Line::List& lines);
211
212private:
213 void appendPathLine(const Line& line);
214 void dumpPathLines(const QString &label) const;
215
216 void logText(const char* file, int line, int level, const QString& text) const;
217
218 Point _originPoint;
219 Point _destinationPoint;
220 Rectangle _canvas;
221 QList<Rectangle> _obstacles;
222 Geo::Direction _direction;
223 Geo::Direction _forceDirection;
224 bool _initialDirectionForced;
225 double _firstSegmentLength;
226 bool _complete;
227 int _routingMargin;
228 bool _consolidateEmptyRectangles;
229 bool _routeAroundMargins;
230 double _verticalConstraint;
231 int _debugLevel;
232
233 Line::List _pathLines;
234 Rectangle _originObstacle;
235 Rectangle _destinationObstacle;
236 Rectangle _currentObstacle;
237
238
239 static const int DefaultRoutingMargin = 10;
240};
241
242#endif // PATHROUTER_H
A list of Line objects with spatial query helpers.
Definition line.h:127
Represents a 2D line segment between two Point endpoints.
Definition line.h:28
Orthogonal path-routing algorithm that navigates around rectangular obstacles.
Definition pathrouter.h:22
Point originPoint() const
Return the origin point.
Definition pathrouter.h:68
void setRouteAroundMargins(bool value)
Enable or disable routing around obstacle margins.
Definition pathrouter.h:122
void setRoutingMargin(int value)
Set the routing margin applied around each obstacle.
Definition pathrouter.h:98
bool routeAroundMargins() const
Return whether the router routes around obstacle margins.
Definition pathrouter.h:116
void setInitialDirection(Geo::Direction direction)
Force the direction of the first routed segment.
Definition pathrouter.h:128
bool consolidateEmptyRectangles() const
Return whether empty (non-obstacle) rectangles are consolidated before routing.
Definition pathrouter.h:104
Line::List calcluatePath()
Compute the routed path from origin to destination avoiding all obstacles.
PathRouter(const Point &origin, const Point &destination, const QRectF &canvas, const QList< Rectangle > &obstacles=QList< Rectangle >())
Construct a PathRouter with full configuration.
void appendObstacle(const Rectangle &value)
Append a single obstacle rectangle to the routing obstacle set.
Definition pathrouter.h:56
int routingMargin() const
Return the routing margin applied around each obstacle.
Definition pathrouter.h:92
int debugLevel() const
Return the debug verbosity level.
Definition pathrouter.h:152
int verticalConstraint() const
Return the vertical constraint (maximum Y coordinate the path may reach).
Definition pathrouter.h:140
void setObstacles(const QList< Rectangle > &value)
Replace the entire obstacle set.
Definition pathrouter.h:62
void setVerticalConstraint(int value)
Set the vertical constraint (maximum Y the path may reach).
Definition pathrouter.h:146
static void mergeAdjacentLines(Line::List &lines)
Merge adjacent collinear line segments in-place.
void setFirstSegmentLength(double value)
Set the length of the first segment before obstacle avoidance begins.
Definition pathrouter.h:134
void setConsolidateEmptyRectangles(bool value)
Enable or disable consolidation of empty rectangles before routing.
Definition pathrouter.h:110
void setOriginPoint(const Point &value)
Set the origin point.
Definition pathrouter.h:74
Point destinationPoint() const
Return the destination point.
Definition pathrouter.h:80
PathRouter()
Default constructor — creates an unconfigured router with default margin settings.
Definition pathrouter.h:25
void setDebugLevel(int value)
Set the debug verbosity level.
Definition pathrouter.h:158
void setDestinationPoint(const Point &value)
Set the destination point.
Definition pathrouter.h:86
A 2D floating-point point extending QPointF with movement and spatial query methods.
Definition point.h:16
A 2D rectangle extending QRectF with edge, corner, and geometric query helpers.
Definition rectangle.h:16
Geographic type enumerations and string-conversion helpers for Qt geometry types.
Definition geotypes.h:14
Direction
Cardinal directions, aliased to the corresponding Side values.
Definition geo.h:37
@ NoDirection
No direction.
Definition geo.h:38