-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathECConvexPolygon.cpp
More file actions
85 lines (65 loc) · 2.69 KB
/
Copy pathECConvexPolygon.cpp
File metadata and controls
85 lines (65 loc) · 2.69 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
//
// ECConvexPolygon.cpp
//
//
// Created by Yufeng Wu on 1/29/21.
//
//
#include "ECConvexPolygon.h"
#include "ECTriangle.h"
#include <math.h>
#define PI 3.14159265
using namespace std;
// Convex polygon on 2D plane: implementing polygon for non-triangles
ECConvexPolygon::ECConvexPolygon(const std::vector<EC2DPoint> &list) {
listNodes = list;
}
bool ECConvexPolygon::IsConvex() const {
// If there are less than 3 nodes, not a polygon, much less a convex one
if (listNodes.size() < 3) { return false; }
// Create a vector of all the line segments that make up the polygon
vector<ECLineSegment> polyLines;
for (int i = 0; i < listNodes.size(); i++) {
EC2DPoint p1 = listNodes[i];
EC2DPoint p2 = listNodes[(i+1)%listNodes.size()];
ECLineSegment seg(p1,p2);
polyLines.push_back(seg);
}
// For each line, do some math
// Math relies on the angle between two lines equals the difference of two angles of inclination
// Each line's angle of inclination is equal to the arctan of the slope
for (int i = 0; i < polyLines.size(); i++) {
ECLineSegment seg1 = polyLines[i];
ECLineSegment seg2 = polyLines[(i+1)%polyLines.size()];
EC2DPoint p1 = seg1.pStart;
EC2DPoint p2 = seg2.pStart;
EC2DPoint p3 = seg2.pEnd;
double slope1 = (p2.yCoord - p1.yCoord) / (p2.xCoord - p1.xCoord);
double slope2 = (p3.yCoord - p2.yCoord) / (p3.xCoord - p2.xCoord);
// Calculate angles of inclination, multiplying by 180/pi to get in degrees
double angle1 = abs(atan(slope1) * (180/PI));
double angle2 = abs(atan(slope2) * (180/PI));
double totalAngle = abs(angle1 - angle2);
// Arctan will return the acute angle, if the angle is obtuse it will come back as 0
// An obtuse angle, greater than 180 means it is not convex
//if (totalAngle > 180) { return false; }
if (totalAngle == 0) { return false; }
}
// If there aren't any obtuse angles, it is convex
return true;
}
// Shoelace Formula
// https://en.wikipedia.org/wiki/Shoelace_formula#:~:text=The%20shoelace%20formula%2C%20shoelace%20algorithm,Cartesian%20coordinates%20in%20the%20plane.
double ECConvexPolygon::GetArea() const {
double area = 0.0;
// Not a polygon = no area
if (listNodes.size() < 3) { return area; }
// Do shoelace formula, I don't understand the math so I won't try to explain it
std::vector<EC2DPoint> nodes = listNodes;
int j = nodes.size() - 1;
for (int i = 0; i < nodes.size(); i++) {
area += (nodes[i].xCoord + nodes[j].xCoord) * (nodes[j].yCoord - nodes[i].yCoord);
j = i;
}
return abs(area / 2.0);
}