Locus No Pilotus
Project of four first grade MIPT DAFE/RSE students (for engineering practical work in the second semester) in Qt C++
Loading...
Searching...
No Matches
math Namespace Reference

Classes

class  AdjacencyMatrix
 Матрица смежности для алгоритма Литтла More...
 
class  CircleObstacle
 Круговое препятствие More...
 
class  DijkstrasAlgorithm
 Реализация алгоритма Дейкстры More...
 
struct  Edge
 Ребро между двумя контрольными точками More...
 
struct  LinearFunction
 Прямая вида ax+by+c=0. More...
 
struct  Minimums
 Структура для хранения двух минимумов строки/столбца More...
 
class  OptimalWayCalculator
 Функтор, находящий кратчайший путь между точками More...
 
struct  PathWayGraph
 Граф вершин между контрольными точками More...
 
struct  PathWayNode
 Вершина графа More...
 
struct  Point
 Точка с геометрическими связями More...
 
class  PolygonObstacle
 Многоугольное препятствие More...
 
class  TrajectoryCalculator
 
class  TravellingSalesmansProblem
 Решение задачи коммивояжера More...
 
struct  TSPNode
 Вершина дерева с соответствующей матрицей смежности More...
 

Functions

bool AreThereIntersections (const CircleObstacle &cr_obst, const LinearFunction &line)
 Проверяет, пересекает ли прямая многоугольник
 
bool AreThereIntersections (const CircleObstacle &cr_obst, const Point &pnt1, const Point &pnt2)
 Проверяет, пересекает ли отрезок, проведенный через две точки, окружность
 
bool AreThereIntersections (const PolygonObstacle &poly_obst, const LinearFunction &line)
 Проверяет, пересекает ли прямая многоугольник
 
bool AreThereIntersections (const PolygonObstacle &poly_obst, const Point &pnt1, const Point &pnt2)
 Проверяет, пересекает ли отрезок, проведенный через две точки, многоугольник
 
double DistanceBetweenPointsOnCircle (const CircleObstacle &circle, const Point &p1, const Point &p2)
 
double DistanceBetweenPointsOnPolygon (const PolygonObstacle &polygon, const Point &p1, const Point &p2)
 
bool IsPointInsideCircle (const Point &point, const CircleObstacle &circle)
 Проверяет, находится ли точка внутри окружности
 
std::pair< Point, PointTangentPoints (const CircleObstacle &cr_obst, const Point &point)
 Находит точки касания круга c касательной, проведенной из контрольной точки
 
std::pair< Point, PointTangentPoints (const LinearFunction &tangent, const CircleObstacle &circle1, const CircleObstacle &circle2)
 Находит точки касания кругов с их общей касательной
 
std::pair< Point, PointTangentPoints (const LinearFunction &tangent, const PolygonObstacle &polygon, const CircleObstacle &circle)
 Находит точки касания многоугольника и круга с их общей касательной
 
std::pair< Point, PointTangentPoints (const LinearFunction &tangent, const PolygonObstacle &polygon1, const PolygonObstacle &polygon2)
 Находит точки касания двух многоугольников с их общей касательной
 
std::pair< Point, PointTangentPoints (const PolygonObstacle &poly_obst, const Point &point)
 Находит точки касания многоугольника c касательной, проведенной из контрольной точки
 
std::vector< LinearFunctionTangentsBetween (const CircleObstacle &circle1, const CircleObstacle &circle2)
 Находит уравнения общих касательных двух кругов
 
template<typename T >
std::vector< LinearFunctionTangentsBetween (const PolygonObstacle &polygon, const T &obstacle)
 Находит уравнения общих касательных многоугольника и другого препятствия
 
template std::vector< LinearFunctionTangentsBetween< CircleObstacle > (const PolygonObstacle &polygon, const CircleObstacle &obstacle)
 
template std::vector< LinearFunctionTangentsBetween< PolygonObstacle > (const PolygonObstacle &polygon, const PolygonObstacle &obstacle)
 

Function Documentation

◆ AreThereIntersections() [1/4]

bool math::AreThereIntersections ( const CircleObstacle & cr_obst,
const LinearFunction & line )

Проверяет, пересекает ли прямая многоугольник

Parameters
cr_obstкруг
lineпрямая
Returns
bool: результат проверки
254 {
255 Point center = cr_obst.GetCenter();
256 double radius = cr_obst.GetRadius();
257 double dist =
258 std::abs(line.a_coef * center.x + line.b_coef * center.y + line.c_coef) /
259 sqrt(pow(line.a_coef, 2) + pow(line.b_coef, 2));
260 return dist < radius - precision;
261}
Point GetCenter() const
Definition obstacles.h:70
double GetRadius() const
Definition obstacles.h:72
double y
Definition point.h:18
double x
Definition point.h:17
double a_coef
Definition obstacles.h:32
double c_coef
Definition obstacles.h:32
double b_coef
Definition obstacles.h:32
Точка с геометрическими связями
Definition obstacles.h:46
Here is the call graph for this function:

◆ AreThereIntersections() [2/4]

bool math::AreThereIntersections ( const CircleObstacle & cr_obst,
const Point & pnt1,
const Point & pnt2 )

Проверяет, пересекает ли отрезок, проведенный через две точки, окружность

Parameters
cr_obstкруг
pnt1точка 1
pnt2точка 2
Returns
bool: результат проверки
227 {
228 double distance = 0;
229 Point center = cr_obst.GetCenter();
230 double radius = cr_obst.GetRadius();
231 Point vector_p1_c = center - point1;
232 Point vector_p2_c = center - point2;
233 Point vector_p1_p2 = point2 - point1;
234 auto module = [](Point p) {
235 return lib::DistanceBetweenPoints(p, Point(0, 0));
236 };
237 auto scalar = [](Point p1, Point p2) { return p1.x * p2.x + p1.y * p2.y; };
238 auto vect = [](Point p1, Point p2) {
239 return std::abs(p1.x * p2.y - p1.y * p2.x);
240 };
241
242 if (scalar(vector_p1_p2, vector_p2_c) >= precision) {
243 distance = module(vector_p2_c);
244 } else if (scalar(vector_p1_p2, vector_p1_c) <= -precision) {
245 distance = module(vector_p1_c);
246 } else {
247 distance = vect(vector_p1_p2, vector_p1_c) / module(vector_p1_p2);
248 }
249 if (distance - radius <= -precision) return true;
250 return false;
251}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AreThereIntersections() [3/4]

bool math::AreThereIntersections ( const PolygonObstacle & poly_obst,
const LinearFunction & line )

Проверяет, пересекает ли прямая многоугольник

Parameters
poly_obstмногоугольник
lineпрямая
Returns
bool: результат проверки
288 {
289 std::vector<Point> vertexes = poly_obst.GetVertexes();
290 for (std::size_t i = 0; i < vertexes.size(); ++i)
291 if ((line.Substitute(vertexes[i]) *
292 line.Substitute(vertexes[(i + 1) % vertexes.size()]) <
293 -precision))
294 return true;
295
296 std::size_t prev = ULLONG_MAX;
297 for (std::size_t i = 0; i < vertexes.size(); ++i)
298 if (std::abs(line.Substitute(vertexes[i])) <= precision) {
299 if ((prev + 1 == 0) || (i - prev == 1) ||
300 (i - prev == vertexes.size() - 1))
301 prev = i;
302 else
303 return true;
304 }
305 return false;
306}
std::vector< Point > GetVertexes() const
Definition obstacles.h:119
double Substitute(const lib::Point &p) const
Definition obstacles.h:28
Here is the call graph for this function:

◆ AreThereIntersections() [4/4]

bool math::AreThereIntersections ( const PolygonObstacle & poly_obst,
const Point & pnt1,
const Point & pnt2 )

Проверяет, пересекает ли отрезок, проведенный через две точки, многоугольник

Parameters
poly_obstмногоугольник
pnt1точка 1
pnt2точка 2
Returns
bool: результат проверки
264 {
265 LinearFunction line(pnt1, pnt2);
266 std::vector<Point> vertexes = poly_obst.GetVertexes();
267 for (std::size_t i = 0; i < vertexes.size(); ++i) {
268 LinearFunction v_line(vertexes[i], vertexes[(i + 1) % vertexes.size()]);
269 if ((line.Substitute(vertexes[i]) *
270 line.Substitute(vertexes[(i + 1) % vertexes.size()]) <
271 -precision) &&
272 (v_line.Substitute(pnt1) * v_line.Substitute(pnt2) < -precision))
273 return true;
274 }
275 std::size_t prev = ULLONG_MAX;
276 for (std::size_t i = 0; i < vertexes.size(); ++i)
277 if (std::abs(line.Substitute(vertexes[i])) <= precision) {
278 if ((prev + 1 == 0) || (i - prev == 1) ||
279 (i - prev == vertexes.size() - 1))
280 prev = i;
281 else
282 return true;
283 }
284 return false;
285}
Прямая вида ax+by+c=0.
Definition obstacles.h:17
Here is the call graph for this function:

◆ DistanceBetweenPointsOnCircle()

double math::DistanceBetweenPointsOnCircle ( const CircleObstacle & circle,
const Point & p1,
const Point & p2 )
12 {
13 if (p1 == p2) return 0;
14 double line = lib::DistanceBetweenPoints(p1, p2);
15 double cos_alpha = (2 * pow(circle.GetRadius(), 2) - pow(line, 2)) /
16 (2 * pow(circle.GetRadius(), 2));
17 return std::abs(cos_alpha) < 1 ? circle.GetRadius() * acos(cos_alpha)
18 : circle.GetRadius() * M_PI;
19}
double DistanceBetweenPoints(const Point &first_point, const Point &second_point)
Находит расстояние между двумя мат. точками
Definition point.cpp:27
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DistanceBetweenPointsOnPolygon()

double math::DistanceBetweenPointsOnPolygon ( const PolygonObstacle & polygon,
const Point & p1,
const Point & p2 )
22 {
23 std::vector<Point> vertexes = polygon.GetVertexes();
24 std::size_t index1 = std::distance(
25 vertexes.begin(), std::find(vertexes.begin(), vertexes.end(), p1));
26 std::size_t index2 = std::distance(
27 vertexes.begin(), std::find(vertexes.begin(), vertexes.end(), p2));
28 std::size_t iter = index1;
29 double d1 = 0;
30 while (iter != index2) {
31 d1 += lib::DistanceBetweenPoints(vertexes[iter],
32 vertexes[(iter + 1) % vertexes.size()]);
33 iter = (iter + 1) % vertexes.size();
34 }
35
36 double d2 = 0;
37 while (iter != index1) {
38 d2 += lib::DistanceBetweenPoints(vertexes[iter],
39 vertexes[(iter + 1) % vertexes.size()]);
40 iter = (iter + 1) % vertexes.size();
41 }
42 return std::min(d1, d2);
43}
Here is the call graph for this function:

◆ IsPointInsideCircle()

bool math::IsPointInsideCircle ( const Point & point,
const CircleObstacle & circle )

Проверяет, находится ли точка внутри окружности

Parameters
pointточка
circleокружность
Returns
bool: результат проверки
308 {
309 return (DistanceBetweenPoints(circle.GetCenter(), point) -
310 circle.GetRadius()) < 0;
311}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TangentPoints() [1/5]

std::pair< Point, Point > math::TangentPoints ( const CircleObstacle & cr_obst,
const Point & point )

Находит точки касания круга c касательной, проведенной из контрольной точки

Parameters
cr_obstкруг
pointконтрольная точка
Returns
std::pair<Point, Point>: точки касательной
109 {
110 Point center = cr_obst.GetCenter();
111 double radius = cr_obst.GetRadius();
112 double dist = lib::DistanceBetweenPoints(center, point);
113 // Угол между касательной и отрезком, соединяющим точку и центр круга
114 double theta = acos(radius / dist);
115 double delta = atan2(point.y - center.y, point.x - center.x);
116 double delta1 = delta + theta;
117 double delta2 = delta - theta;
118 double x1_tang_pnt = center.x + radius * cos(delta1);
119 double x2_tang_pnt = center.x + radius * cos(delta2);
120 double y1_tang_pnt = center.y + radius * sin(delta1);
121 double y2_tang_pnt = center.y + radius * sin(delta2);
122 return std::make_pair(Point(x1_tang_pnt, y1_tang_pnt),
123 Point(x2_tang_pnt, y2_tang_pnt));
124}
Here is the call graph for this function:

◆ TangentPoints() [2/5]

std::pair< Point, Point > math::TangentPoints ( const LinearFunction & tangent,
const CircleObstacle & circle1,
const CircleObstacle & circle2 )

Находит точки касания кругов с их общей касательной

Parameters
tangentкасательная
circle1круг 1
circle2круг 2
Returns
std::pair<Point, Point>: точки касательной
47 {
48 double a = tangent.a_coef;
49 double b = tangent.b_coef;
50 double c = tangent.c_coef;
51 double x_0 = circle1.GetCenter().x;
52 double y_0 = circle1.GetCenter().y;
53 double x_1 = circle2.GetCenter().x;
54 double y_1 = circle2.GetCenter().y;
55 double point1_x =
56 (x_0 * pow(b, 2) - (a * (c + y_0 * b))) / (pow(a, 2) + pow(b, 2));
57 double point2_x =
58 (x_1 * pow(b, 2) - (a * (c + y_1 * b))) / (pow(a, 2) + pow(b, 2));
59 double point1_y, point2_y;
60 if (std::abs(b) > precision) {
61 point1_y = a / b * (-point1_x) - c / b;
62 point2_y = a / b * (-point2_x) - c / b;
63 } else {
64 point1_y = y_0;
65 point2_y = y_1;
66 }
67 Point point1(point1_x, point1_y);
68 Point point2(point2_x, point2_y);
69 return std::make_pair(point1, point2);
70}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TangentPoints() [3/5]

std::pair< Point, Point > math::TangentPoints ( const LinearFunction & tangent,
const PolygonObstacle & polygon,
const CircleObstacle & circle )

Находит точки касания многоугольника и круга с их общей касательной

Parameters
tangentкасательная
polygonмногоугольник
circleкруг
Returns
std::pair<Point, Point>: точки касательной
92 {
93 std::pair<Point, Point> tang_pnts;
94 std::vector<Point> vertexes = polygon.GetVertexes();
95 for (auto& vertex : vertexes)
96 if (std::abs(tangent.a_coef * vertex.x + tangent.b_coef * vertex.y +
97 tangent.c_coef) <= precision)
98 tang_pnts.first = vertex;
99
100 std::pair<Point, Point> cr_points = TangentPoints(circle, tang_pnts.first);
101 for (auto& point : {cr_points.first, cr_points.second})
102 if (std::abs(tangent.a_coef * point.x + tangent.b_coef * point.y +
103 tangent.c_coef) <= precision)
104 tang_pnts.second = point;
105 return tang_pnts;
106}
std::pair< Point, Point > TangentPoints(const LinearFunction &tangent, const CircleObstacle &circle1, const CircleObstacle &circle2)
Находит точки касания кругов с их общей касательной
Definition helpers_functions.cpp:45
Here is the call graph for this function:

◆ TangentPoints() [4/5]

std::pair< Point, Point > math::TangentPoints ( const LinearFunction & tangent,
const PolygonObstacle & polygon1,
const PolygonObstacle & polygon2 )

Находит точки касания двух многоугольников с их общей касательной

Parameters
tangentкасательная
polygon1многоугольник 1
polygon2многоугольник 2
Returns
std::pair<Point, Point>: точки касательной
74 {
75 std::pair<Point, Point> tang_pnts;
76 std::vector<Point> vertexes1 = polygon1.GetVertexes();
77 for (auto& vertex : vertexes1)
78 if (std::abs(tangent.a_coef * vertex.x + tangent.b_coef * vertex.y +
79 tangent.c_coef) <= precision)
80 tang_pnts.first = vertex;
81
82 std::vector<Point> vertexes2 = polygon2.GetVertexes();
83 for (auto& vertex : vertexes2)
84 if (std::abs(tangent.a_coef * vertex.x + tangent.b_coef * vertex.y +
85 tangent.c_coef) <= precision)
86 tang_pnts.second = vertex;
87 return tang_pnts;
88}
Here is the call graph for this function:

◆ TangentPoints() [5/5]

std::pair< Point, Point > math::TangentPoints ( const PolygonObstacle & poly_obst,
const Point & point )

Находит точки касания многоугольника c касательной, проведенной из контрольной точки

Parameters
poly_obstмногоугольник
pointконтрольная точка
Returns
std::pair<Point, Point>: точки касательной
127 {
128 Point center = poly_obst.GetCenter();
129 std::vector<Point> vertexes = poly_obst.GetVertexes();
130 Point tang_pnt_1 = vertexes[0];
131 double cos_alpha_1 = 1;
132 Point tang_pnt_2;
133 double cos_alpha_2 = 1;
134 double dist_to_cnt = lib::DistanceBetweenPoints(center, point);
135 LinearFunction line(center, point);
136 for (const auto& vertex : vertexes)
137 if (line.Substitute(vertex) * line.Substitute(vertexes[0]) < 0) {
138 tang_pnt_2 = vertex;
139 break;
140 }
141 for (const auto& vertex : vertexes) {
142 double dist_to_vrtx = lib::DistanceBetweenPoints(vertex, point);
143 double dist_cnt_vrtx = lib::DistanceBetweenPoints(center, vertex);
144 double new_cos_alpha =
145 (pow(dist_to_vrtx, 2) + pow(dist_to_cnt, 2) - pow(dist_cnt_vrtx, 2)) /
146 (2 * dist_to_vrtx * dist_to_cnt);
147 if ((line.Substitute(vertex) * line.Substitute(tang_pnt_1) > 0) &&
148 (new_cos_alpha < cos_alpha_1)) {
149 tang_pnt_1 = vertex;
150 cos_alpha_1 = new_cos_alpha;
151 } else if ((line.Substitute(vertex) * line.Substitute(tang_pnt_2) > 0) &&
152 (new_cos_alpha < cos_alpha_2)) {
153 tang_pnt_2 = vertex;
154 cos_alpha_2 = new_cos_alpha;
155 }
156 }
157 return std::make_pair(tang_pnt_1, tang_pnt_2);
158}
Point GetCenter() const
Definition obstacles.h:117
Here is the call graph for this function:

◆ TangentsBetween() [1/2]

std::vector< LinearFunction > math::TangentsBetween ( const CircleObstacle & circle1,
const CircleObstacle & circle2 )

Находит уравнения общих касательных двух кругов

Parameters
circle1круг 1
circle2круг 2
Returns
std::vector<LinearFunction>: уравнения касательных
161 {
162 std::vector<LinearFunction> tangents;
163 double x_1 = circle2.GetCenter().x;
164 double y_1 = circle2.GetCenter().y;
165 double r_1 = circle2.GetRadius();
166 double x_0 = circle1.GetCenter().x;
167 double y_0 = circle1.GetCenter().y;
168 double r_0 = circle1.GetRadius();
169
170 auto FindTangent = [&x_1, &x_0, &y_1, &y_0](double r_0, double r_1) {
171 double a, b, c;
172 if (std::abs(x_1 - x_0) > precision) {
173 double root = pow(x_1 - x_0, 2) *
174 (pow(x_1 - x_0, 2) + pow(y_1 - y_0, 2) - pow(r_1 - r_0, 2));
175 if (std::abs(root) < precision)
176 root = 0;
177 else
178 root = sqrt(root);
179 b = ((r_1 - r_0) * (y_1 - y_0) + root) /
180 (pow(x_1 - x_0, 2) + pow(y_1 - y_0, 2));
181
182 a = ((r_1 - r_0) - b * (y_1 - y_0)) / (x_1 - x_0);
183
184 c = r_0 - a * x_0 - b * y_0;
185 } else {
186 a = std::abs(y_1 - y_0) / sqrt(pow(r_1 - r_0, 2) + pow(y_1 - y_0, 2));
187 b = (r_1 - r_0) / sqrt(pow(r_1 - r_0, 2) + pow(y_1 - y_0, 2));
188 c = r_0 - a * x_0 - b * y_0;
189 }
190
191 return LinearFunction(a, b, c);
192 };
193
194 for (auto n1 : {-1, 1})
195 for (auto n2 : {-1, 1}) {
196 bool is_unique = !(std::isnan(FindTangent(r_0 * n1, r_1 * n2).a_coef));
197 for (std::size_t i = 0; i < tangents.size(); ++i)
198 if (tangents[i] == FindTangent(r_0 * n1, r_1 * n2)) is_unique = false;
199 if (is_unique) tangents.push_back(FindTangent(r_0 * n1, r_1 * n2));
200 }
201 return tangents;
202}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TangentsBetween() [2/2]

template<typename T >
std::vector< LinearFunction > math::TangentsBetween ( const PolygonObstacle & polygon,
const T & obstacle )

Находит уравнения общих касательных многоугольника и другого препятствия

Parameters
polygonмногоугольник
obstacleпрепятствие
Returns
уравнения касательных
206 {
207 std::vector<LinearFunction> tangents;
208 std::vector<Point> vertexes = polygon.GetVertexes();
209 for (auto& vertex : vertexes) {
210 std::pair<Point, Point> tang_pnts = TangentPoints(obstacle, vertex);
211 for (auto& tang_pnt : {tang_pnts.first, tang_pnts.second})
212 if (vertex != tang_pnt) {
213 LinearFunction line(vertex, tang_pnt);
214 if ((!AreThereIntersections(polygon, line)) &&
215 (!AreThereIntersections(obstacle, line))) {
216 bool is_unique = !std::isnan(line.a_coef);
217 for (std::size_t i = 0; i < tangents.size(); ++i)
218 if (tangents[i] == line) is_unique = false;
219 if (is_unique) tangents.push_back(line);
220 }
221 }
222 }
223 return tangents;
224}
Here is the call graph for this function:

◆ TangentsBetween< CircleObstacle >()

template std::vector< LinearFunction > math::TangentsBetween< CircleObstacle > ( const PolygonObstacle & polygon,
const CircleObstacle & obstacle )

◆ TangentsBetween< PolygonObstacle >()

template std::vector< LinearFunction > math::TangentsBetween< PolygonObstacle > ( const PolygonObstacle & polygon,
const PolygonObstacle & obstacle )