-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPolygon.cpp
More file actions
95 lines (81 loc) · 3.26 KB
/
Polygon.cpp
File metadata and controls
95 lines (81 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "Polygon.h"
bool Polygon::check_if_point_inside_polygon(Point point) {
int number_of_intersections = 0;
for (int i = 0; i < _vertices.size(); i++) {
Point current = _vertices[i];
Point next = _vertices[(i + 1) % _vertices.size()];
if (current.y != point.y) {
if ((current.y - point.y) * (next.y - point.y) < 0) {
if (get_x_coord_of_line_point(current, next, point.y) >= point.x) {
++number_of_intersections;
}
}
} else {
if (current.x > point.x) {
Point prev = _vertices[(i - 1 + _vertices.size()) % _vertices.size()];
if (next.y != point.y) {
if ((point.y - next.y) * (point.y - prev.y) < 0) {
++number_of_intersections;
}
} else if (next.x <= point.x) {
return true;
} else {
Point next_after_next = _vertices[(i + 2) % _vertices.size()];
if ((next_after_next.y - next.y) * (point.y - prev.y) > 0) {
++number_of_intersections;
} else if ((next_after_next.y - next.y) * (point.y - prev.y) == 0) {
std::cout << "Three points on one line";
}
}
} else if (current.x < point.x) {
if (next.x >= point.x && next.y == point.y) {
return true;
}
} else {
return true;
}
}
}
return number_of_intersections % 2 != 0;
}
std::istream &operator>>(std::istream &in, Polygon &polygon) {
unsigned long no_of_vertices;
in >> no_of_vertices;
polygon._vertices.clear();
polygon._vertices.reserve(no_of_vertices);
//first two vertices
Point point;
in >> point;
polygon._vertices.push_back(point);
in >> point;
polygon._vertices.push_back(point);
for (int i = 2; i < no_of_vertices; ++i) {
in >> point;
//if three point are on one line we need to delete middle point
if (point.y == polygon._vertices[polygon._vertices.size() - 1].y &&
point.y == polygon._vertices[polygon._vertices.size() - 2].y) {
polygon._vertices.pop_back();
}
polygon._vertices.push_back(point);
}
if (polygon._vertices[polygon._vertices.size() - 1].y == polygon._vertices[0].y &&
polygon._vertices[polygon._vertices.size() - 1].y == polygon._vertices[1].y) {
polygon._vertices.erase(polygon._vertices.begin(), polygon._vertices.begin() + 1);
}
if (polygon._vertices[polygon._vertices.size() - 1].y == polygon._vertices[0].y &&
polygon._vertices[polygon._vertices.size() - 2].y == polygon._vertices[0].y) {
polygon._vertices.pop_back();
}
return in;
}
Polygon::Polygon() :
_vertices() {
}
int Polygon::get_x_coord_of_line_point(Point line_point_a, Point line_point_b, int y) {
if (line_point_a.x == line_point_b.x) {
return line_point_a.x;
} else {
double k = (double)(line_point_b.y - line_point_a.y) / (double)(line_point_b.x - line_point_a.x);
return (int) (line_point_a.x + (y - line_point_a.y) / k);
}
}