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: результат проверки
252 {
253 Point center = cr_obst.GetCenter();
254 double radius = cr_obst.GetRadius();
255 double dist =
256 std::abs(line.a_coef * center.x + line.b_coef * center.y + line.c_coef) /
257 sqrt(pow(line.a_coef, 2) + pow(line.b_coef, 2));
258 return dist < radius - precision;
259}
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: результат проверки
225 {
226 double distance = 0;
227 Point center = cr_obst.GetCenter();
228 double radius = cr_obst.GetRadius();
229 Point vector_p1_c = center - point1;
230 Point vector_p2_c = center - point2;
231 Point vector_p1_p2 = point2 - point1;
232 auto module = [](Point p) {
233 return lib::DistanceBetweenPoints(p, Point(0, 0));
234 };
235 auto scalar = [](Point p1, Point p2) { return p1.x * p2.x + p1.y * p2.y; };
236 auto vect = [](Point p1, Point p2) {
237 return std::abs(p1.x * p2.y - p1.y * p2.x);
238 };
239
240 if (scalar(vector_p1_p2, vector_p2_c) >= precision) {
241 distance = module(vector_p2_c);
242 } else if (scalar(vector_p1_p2, vector_p1_c) <= -precision) {
243 distance = module(vector_p1_c);
244 } else {
245 distance = vect(vector_p1_p2, vector_p1_c) / module(vector_p1_p2);
246 }
247 if (distance - radius <= -precision) return true;
248 return false;
249}
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: результат проверки
286 {
287 std::vector<Point> vertexes = poly_obst.GetVertexes();
288 for (std::size_t i = 0; i < vertexes.size(); ++i)
289 if ((line.Substitute(vertexes[i]) *
290 line.Substitute(vertexes[(i + 1) % vertexes.size()]) <
291 -precision))
292 return true;
293
294 std::size_t prev = ULONG_LONG_MAX;
295 for (std::size_t i = 0; i < vertexes.size(); ++i)
296 if (std::abs(line.Substitute(vertexes[i])) <= precision) {
297 if ((prev + 1 == 0) || (i - prev == 1) ||
298 (i - prev == vertexes.size() - 1))
299 prev = i;
300 else
301 return true;
302 }
303 return false;
304}
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: результат проверки
262 {
263 LinearFunction line(pnt1, pnt2);
264 std::vector<Point> vertexes = poly_obst.GetVertexes();
265 for (std::size_t i = 0; i < vertexes.size(); ++i) {
266 LinearFunction v_line(vertexes[i], vertexes[(i + 1) % vertexes.size()]);
267 if ((line.Substitute(vertexes[i]) *
268 line.Substitute(vertexes[(i + 1) % vertexes.size()]) <
269 -precision) &&
270 (v_line.Substitute(pnt1) * v_line.Substitute(pnt2) < -precision))
271 return true;
272 }
273 std::size_t prev = ULONG_LONG_MAX;
274 for (std::size_t i = 0; i < vertexes.size(); ++i)
275 if (std::abs(line.Substitute(vertexes[i])) <= precision) {
276 if ((prev + 1 == 0) || (i - prev == 1) ||
277 (i - prev == vertexes.size() - 1))
278 prev = i;
279 else
280 return true;
281 }
282 return false;
283}
Прямая вида 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 )
10 {
11 if (p1 == p2) return 0;
12 double line = lib::DistanceBetweenPoints(p1, p2);
13 double cos_alpha = (2 * pow(circle.GetRadius(), 2) - pow(line, 2)) /
14 (2 * pow(circle.GetRadius(), 2));
15 return std::abs(cos_alpha) < 1 ? circle.GetRadius() * acos(cos_alpha)
16 : circle.GetRadius() * M_PI;
17}
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 )
20 {
21 std::vector<Point> vertexes = polygon.GetVertexes();
22 std::size_t index1 = std::distance(
23 vertexes.begin(), std::find(vertexes.begin(), vertexes.end(), p1));
24 std::size_t index2 = std::distance(
25 vertexes.begin(), std::find(vertexes.begin(), vertexes.end(), p2));
26 std::size_t iter = index1;
27 double d1 = 0;
28 while (iter != index2) {
29 d1 += lib::DistanceBetweenPoints(vertexes[iter],
30 vertexes[(iter + 1) % vertexes.size()]);
31 iter = (iter + 1) % vertexes.size();
32 }
33
34 double d2 = 0;
35 while (iter != index1) {
36 d2 += lib::DistanceBetweenPoints(vertexes[iter],
37 vertexes[(iter + 1) % vertexes.size()]);
38 iter = (iter + 1) % vertexes.size();
39 }
40 return std::min(d1, d2);
41}
Here is the call graph for this function:

◆ IsPointInsideCircle()

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

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

Parameters
pointточка
circleокружность
Returns
bool: результат проверки
306 {
307 return (DistanceBetweenPoints(circle.GetCenter(), point) -
308 circle.GetRadius()) < 0;
309}
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>: точки касательной
107 {
108 Point center = cr_obst.GetCenter();
109 double radius = cr_obst.GetRadius();
110 double dist = lib::DistanceBetweenPoints(center, point);
111 // Угол между касательной и отрезком, соединяющим точку и центр круга
112 double theta = acos(radius / dist);
113 double delta = atan2(point.y - center.y, point.x - center.x);
114 double delta1 = delta + theta;
115 double delta2 = delta - theta;
116 double x1_tang_pnt = center.x + radius * cos(delta1);
117 double x2_tang_pnt = center.x + radius * cos(delta2);
118 double y1_tang_pnt = center.y + radius * sin(delta1);
119 double y2_tang_pnt = center.y + radius * sin(delta2);
120 return std::make_pair(Point(x1_tang_pnt, y1_tang_pnt),
121 Point(x2_tang_pnt, y2_tang_pnt));
122}
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>: точки касательной
45 {
46 double a = tangent.a_coef;
47 double b = tangent.b_coef;
48 double c = tangent.c_coef;
49 double x_0 = circle1.GetCenter().x;
50 double y_0 = circle1.GetCenter().y;
51 double x_1 = circle2.GetCenter().x;
52 double y_1 = circle2.GetCenter().y;
53 double point1_x =
54 (x_0 * pow(b, 2) - (a * (c + y_0 * b))) / (pow(a, 2) + pow(b, 2));
55 double point2_x =
56 (x_1 * pow(b, 2) - (a * (c + y_1 * b))) / (pow(a, 2) + pow(b, 2));
57 double point1_y, point2_y;
58 if (std::abs(b) > precision) {
59 point1_y = a / b * (-point1_x) - c / b;
60 point2_y = a / b * (-point2_x) - c / b;
61 } else {
62 point1_y = y_0;
63 point2_y = y_1;
64 }
65 Point point1(point1_x, point1_y);
66 Point point2(point2_x, point2_y);
67 return std::make_pair(point1, point2);
68}
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>: точки касательной
90 {
91 std::pair<Point, Point> tang_pnts;
92 std::vector<Point> vertexes = polygon.GetVertexes();
93 for (auto& vertex : vertexes)
94 if (std::abs(tangent.a_coef * vertex.x + tangent.b_coef * vertex.y +
95 tangent.c_coef) <= precision)
96 tang_pnts.first = vertex;
97
98 std::pair<Point, Point> cr_points = TangentPoints(circle, tang_pnts.first);
99 for (auto& point : {cr_points.first, cr_points.second})
100 if (std::abs(tangent.a_coef * point.x + tangent.b_coef * point.y +
101 tangent.c_coef) <= precision)
102 tang_pnts.second = point;
103 return tang_pnts;
104}
std::pair< Point, Point > TangentPoints(const LinearFunction &tangent, const CircleObstacle &circle1, const CircleObstacle &circle2)
Находит точки касания кругов с их общей касательной
Definition helpers_functions.cpp:43
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>: точки касательной
72 {
73 std::pair<Point, Point> tang_pnts;
74 std::vector<Point> vertexes1 = polygon1.GetVertexes();
75 for (auto& vertex : vertexes1)
76 if (std::abs(tangent.a_coef * vertex.x + tangent.b_coef * vertex.y +
77 tangent.c_coef) <= precision)
78 tang_pnts.first = vertex;
79
80 std::vector<Point> vertexes2 = polygon2.GetVertexes();
81 for (auto& vertex : vertexes2)
82 if (std::abs(tangent.a_coef * vertex.x + tangent.b_coef * vertex.y +
83 tangent.c_coef) <= precision)
84 tang_pnts.second = vertex;
85 return tang_pnts;
86}
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>: точки касательной
125 {
126 Point center = poly_obst.GetCenter();
127 std::vector<Point> vertexes = poly_obst.GetVertexes();
128 Point tang_pnt_1 = vertexes[0];
129 double cos_alpha_1 = 1;
130 Point tang_pnt_2;
131 double cos_alpha_2 = 1;
132 double dist_to_cnt = lib::DistanceBetweenPoints(center, point);
133 LinearFunction line(center, point);
134 for (const auto& vertex : vertexes)
135 if (line.Substitute(vertex) * line.Substitute(vertexes[0]) < 0) {
136 tang_pnt_2 = vertex;
137 break;
138 }
139 for (const auto& vertex : vertexes) {
140 double dist_to_vrtx = lib::DistanceBetweenPoints(vertex, point);
141 double dist_cnt_vrtx = lib::DistanceBetweenPoints(center, vertex);
142 double new_cos_alpha =
143 (pow(dist_to_vrtx, 2) + pow(dist_to_cnt, 2) - pow(dist_cnt_vrtx, 2)) /
144 (2 * dist_to_vrtx * dist_to_cnt);
145 if ((line.Substitute(vertex) * line.Substitute(tang_pnt_1) > 0) &&
146 (new_cos_alpha < cos_alpha_1)) {
147 tang_pnt_1 = vertex;
148 cos_alpha_1 = new_cos_alpha;
149 } else if ((line.Substitute(vertex) * line.Substitute(tang_pnt_2) > 0) &&
150 (new_cos_alpha < cos_alpha_2)) {
151 tang_pnt_2 = vertex;
152 cos_alpha_2 = new_cos_alpha;
153 }
154 }
155 return std::make_pair(tang_pnt_1, tang_pnt_2);
156}
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>: уравнения касательных
159 {
160 std::vector<LinearFunction> tangents;
161 double x_1 = circle2.GetCenter().x;
162 double y_1 = circle2.GetCenter().y;
163 double r_1 = circle2.GetRadius();
164 double x_0 = circle1.GetCenter().x;
165 double y_0 = circle1.GetCenter().y;
166 double r_0 = circle1.GetRadius();
167
168 auto FindTangent = [&x_1, &x_0, &y_1, &y_0](double r_0, double r_1) {
169 double a, b, c;
170 if (std::abs(x_1 - x_0) > precision) {
171 double root = pow(x_1 - x_0, 2) *
172 (pow(x_1 - x_0, 2) + pow(y_1 - y_0, 2) - pow(r_1 - r_0, 2));
173 if (std::abs(root) < precision)
174 root = 0;
175 else
176 root = sqrt(root);
177 b = ((r_1 - r_0) * (y_1 - y_0) + root) /
178 (pow(x_1 - x_0, 2) + pow(y_1 - y_0, 2));
179
180 a = ((r_1 - r_0) - b * (y_1 - y_0)) / (x_1 - x_0);
181
182 c = r_0 - a * x_0 - b * y_0;
183 } else {
184 a = std::abs(y_1 - y_0) / sqrt(pow(r_1 - r_0, 2) + pow(y_1 - y_0, 2));
185 b = (r_1 - r_0) / sqrt(pow(r_1 - r_0, 2) + pow(y_1 - y_0, 2));
186 c = r_0 - a * x_0 - b * y_0;
187 }
188
189 return LinearFunction(a, b, c);
190 };
191
192 for (auto n1 : {-1, 1})
193 for (auto n2 : {-1, 1}) {
194 bool is_unique = !(_isnan(FindTangent(r_0 * n1, r_1 * n2).a_coef));
195 for (std::size_t i = 0; i < tangents.size(); ++i)
196 if (tangents[i] == FindTangent(r_0 * n1, r_1 * n2)) is_unique = false;
197 if (is_unique) tangents.push_back(FindTangent(r_0 * n1, r_1 * n2));
198 }
199 return tangents;
200}
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
уравнения касательных
204 {
205 std::vector<LinearFunction> tangents;
206 std::vector<Point> vertexes = polygon.GetVertexes();
207 for (auto& vertex : vertexes) {
208 std::pair<Point, Point> tang_pnts = TangentPoints(obstacle, vertex);
209 for (auto& tang_pnt : {tang_pnts.first, tang_pnts.second})
210 if (vertex != tang_pnt) {
211 LinearFunction line(vertex, tang_pnt);
212 if ((!AreThereIntersections(polygon, line)) &&
213 (!AreThereIntersections(obstacle, line))) {
214 bool is_unique = !_isnan(line.a_coef);
215 for (std::size_t i = 0; i < tangents.size(); ++i)
216 if (tangents[i] == line) is_unique = false;
217 if (is_unique) tangents.push_back(line);
218 }
219 }
220 }
221 return tangents;
222}
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 )