IntelliPhoto 0.5

IntelliTriangulation.cpp
Go to the documentation of this file.
1 #include "IntelliTriangulation.h"
2 #include <algorithm>
3 #include <queue>
4 #include <cmath>
5 #define pi 3.1415926535897932384626433832795
6
7 std::vector<Triangle> IntelliTriangulation::calculateTriangles(std::vector<QPoint> polyPoints){
8 // helper for managing the triangle vertices and their state
9 struct TriangleHelper {
10 QPoint vertex;
11 float interiorAngle;
12 int idx;
13 bool isTip;
14 };
15
16 // calculates the inner angle of 'point'
17 auto calculateInner = [](QPoint& point, QPoint& prev, QPoint& post){
18 QPoint AP(point.x()-prev.x(), point.y()-prev.y());
19 QPoint BP(point.x()-post.x(), point.y()-post.y());
20
21 float topSclar = AP.x()*BP.x()+AP.y()*BP.y();
22 float absolute = static_cast<float>(sqrt(pow(AP.x(),2.)+pow(AP.y(),2.))*sqrt(pow(BP.x(),2.)+pow(BP.y(),2.)));
23 return acos(topSclar/absolute);
24 };
25
26 // gets the first element of vec for which element.isTip == true holds
27 auto getTip= [](const std::vector<TriangleHelper>& vec){
28 size_t min = 0;
29 for(size_t i=0; i<vec.size(); i++) {
30 if(vec[i].interiorAngle<vec[min].interiorAngle) {
31 min = i;
32 }
33 }
34 return vec[min];
35 };
36
37 // get the vertex idx bevor idx in relation to the container length
38 auto getPrev = [](int idx, int length){
39 return (idx-1)>=0 ? (idx-1) : (length-1);
40 };
41
42 // get the vertex idx after idx in relation to the container lenght
43 auto getPost = [](int idx, int length){
44 return (idx+1)%length;
45 };
46
47 // return if the vertex is a tip
48 auto isTip = [](float angle){
49 return static_cast<double>(angle)<(pi/2.);
50 };
51
52 std::vector<TriangleHelper> Vertices;
53 std::vector<Triangle> Triangles;
54
55 // set up all vertices and calculate intirior angle
56 for(int i=0; i<static_cast<int>(polyPoints.size()); i++) {
57 TriangleHelper helper;
58 int prev = getPrev(i, static_cast<int>(polyPoints.size()));
59 int post = getPost(i, static_cast<int>(polyPoints.size()));
60
61 helper.vertex = polyPoints[static_cast<size_t>(i)];
62 helper.idx = i;
63
64 helper.interiorAngle = calculateInner(polyPoints[static_cast<size_t>(i)],
65 polyPoints[static_cast<size_t>(prev)],
66 polyPoints[static_cast<size_t>(post)]);
67 helper.isTip = isTip(helper.interiorAngle);
68 Vertices.push_back(helper);
69 }
70
71 // search triangles based on the intirior angles of each vertey
72 while(Triangles.size() != polyPoints.size()-2) {
73 Triangle tri;
74 TriangleHelper smallest = getTip(Vertices);
75 int prev = getPrev(smallest.idx, static_cast<int>(Vertices.size()));
76 int post = getPost(smallest.idx, static_cast<int>(Vertices.size()));
77
78 // set triangle and push it
79 tri.A = Vertices[static_cast<size_t>(prev)].vertex;
80 tri.B = Vertices[static_cast<size_t>(smallest.idx)].vertex;
81 tri.C = Vertices[static_cast<size_t>(post)].vertex;
82 Triangles.push_back(tri);
83
84 // update Vertice array
85 Vertices.erase(Vertices.begin()+smallest.idx);
86 for(size_t i=static_cast<size_t>(smallest.idx); i<Vertices.size(); i++) {
87 Vertices[i].idx-=1;
88 }
89
90 // update post und prev idx
91 post = getPrev(post, Vertices.size());
92 prev = prev<smallest.idx ? prev : (prev-1);
93
94 // calcultae neighboors of prev and post to calculate new interior angles
95 int prevOfPrev = getPrev(prev, static_cast<int>(Vertices.size()));
96 int postOfPrev = getPost(prev, static_cast<int>(Vertices.size()));
97
98 int prevOfPost = getPrev(post, static_cast<int>(Vertices.size()));
99 int postOfPost = getPost(post, static_cast<int>(Vertices.size()));
100
101 // update vertices with interior angles
102 // updtae prev
103 Vertices[static_cast<size_t>(prev)].interiorAngle = calculateInner(Vertices[static_cast<size_t>(prev)].vertex,
104 Vertices[static_cast<size_t>(prevOfPrev)].vertex,
105 Vertices[static_cast<size_t>(postOfPrev)].vertex);
106 Vertices[static_cast<size_t>(prev)].isTip = isTip(Vertices[static_cast<size_t>(prev)].interiorAngle);
107 // update post
108 Vertices[static_cast<size_t>(post)].interiorAngle = calculateInner(Vertices[static_cast<size_t>(post)].vertex,
109 Vertices[static_cast<size_t>(prevOfPost)].vertex,
110 Vertices[static_cast<size_t>(postOfPost)].vertex);
111 Vertices[static_cast<size_t>(post)].isTip = isTip(Vertices[static_cast<size_t>(post)].interiorAngle);
112 }
113 return Triangles;
114 }
115
116 bool IntelliTriangulation::isInPolygon(std::vector<Triangle> &triangles, QPoint &point){
117 for(auto triangle : triangles) {
118 if(IntelliTriangulation::isInTriangle(triangle, point)) {
119 return true;
120 }
121 }
122 return false;
123 }
IntelliTriangulation::isInTriangle
bool isInTriangle(Triangle &tri, QPoint &P)
A function to check if a given point is in a triangle.
Definition: IntelliTriangulation.h:33
IntelliTriangulation::calculateTriangles
std::vector< Triangle > calculateTriangles(std::vector< QPoint > polyPoints)
A function to split a polygon in its spanning traingles by using Meisters Theorem of graph theory by ...
Definition: IntelliTriangulation.cpp:7
Triangle::B
QPoint B
Definition: IntelliTriangulation.h:11
pi
#define pi
Definition: IntelliTriangulation.cpp:5
Triangle::C
QPoint C
Definition: IntelliTriangulation.h:11
Triangle
The Triangle struct holds the 3 vertices of a triangle.
Definition: IntelliTriangulation.h:10
IntelliTriangulation::isInPolygon
bool isInPolygon(std::vector< Triangle > &triangles, QPoint &point)
A function to check if a point lies in a polygon by checking its spanning triangles.
Definition: IntelliTriangulation.cpp:116
Triangle::A
QPoint A
Definition: IntelliTriangulation.h:11
IntelliTriangulation.h