summaryrefslogtreecommitdiffstats
path: root/Polygon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Polygon.cpp')
-rw-r--r--Polygon.cpp118
1 files changed, 118 insertions, 0 deletions
diff --git a/Polygon.cpp b/Polygon.cpp
new file mode 100644
index 0000000..05d06ca
--- /dev/null
+++ b/Polygon.cpp
@@ -0,0 +1,118 @@
+#include "Polygon.h"
+#include <math.h>
+
+
+double Polygon::area() const {
+ double d = 0.0;
+
+ for(const_iterator it = begin(); it != end(); it++) {
+ const_iterator it2 = it+1;
+ if(it2 == end()) it2 = begin();
+
+ d += (it2->getX()+it->getX())*(it2->getY()-it->getY());
+ }
+
+ return fabs(d/2);
+}
+
+double Polygon::perimeter() const {
+ double d = 0.0;
+
+ for(const_iterator it = begin(); it != end(); it++) {
+ const_iterator it2 = it+1;
+ if(it2 == end()) it2 = begin();
+
+ d += it->distance(*it2);
+ }
+
+ return d;
+}
+
+int Polygon::quadrant(const Vertex &v) const {
+ if(v.getX() > 0 && v.getY() >= 0) return 1;
+ if(v.getX() >= 0 && v.getY() < 0) return 2;
+ if(v.getX() < 0 && v.getY() <= 0) return 3;
+ if(v.getX() <= 0 && v.getY() > 0) return 4;
+
+ return 0;
+}
+
+bool Polygon::contains(const Vertex &v) const {
+ int d = 0;
+ int q, ql, q2;
+ LINE d1 = {Vertex(-1, -1), Vertex(1, 1)};
+ LINE d2 = {Vertex(-1, 1), Vertex(1, -1)};
+ LINE l;
+ Vertex v2;
+
+
+ if(empty()) return false;
+
+ v2 = back() - v;
+ q = quadrant(v2);
+
+ if(q == 0) return true;
+
+ for(const_iterator it = begin(); it != end(); it++) {
+ ql = q;
+
+ v2 = *it - v;
+ q = quadrant(v2);
+
+ if(q == 0) return true;
+
+ switch(q-ql) {
+ case 0:
+ break;
+ case 1:
+ case -3:
+ d++;
+ break;
+ case 3:
+ case -1:
+ d--;
+ break;
+ default:
+ l.v1 = ((it == begin()) ? back() : *(it-1)) - v;
+ l.v2 = v2;
+
+ if(q == 1 || q == 3) {
+ if(!(lineIntersection(&l, &d2, &v2) & INTERSECTION_LINE)) return false;
+
+ q2 = quadrant(v2);
+ if(q2 == 0) return true;
+
+ if((q == 1 && q2 == 2) || (q == 3 && q2 == 4)) d -= 2;
+ else d += 2;
+ }
+ else {
+ if(!(lineIntersection(&l, &d1, &v2) & INTERSECTION_LINE)) return false;
+
+ q2 = quadrant(v2);
+ if(q2 == 0) return true;
+
+ if((q == 2 && q2 == 3) || (q == 4 && q2 == 1)) d -= 2;
+ else d += 2;
+ }
+ }
+ }
+
+ return (d != 0);
+}
+
+bool Polygon::intersects(const LINE *l) const {
+ LINE line;
+
+ for(Polygon::const_iterator it = begin(); it != end(); it++) {
+ Polygon::const_iterator it2 = it+1;
+ if(it2 == end()) it2 = begin();
+
+ line.v1 = *it;
+ line.v2 = *it2;
+
+ if(lineIntersection(l, &line, NULL) == INTERSECTION_SEGMENT_SEGMENT)
+ return true;
+ }
+
+ return false;
+}