IntelliPhoto  0.5
IntelliHelper.cpp
Go to the documentation of this file.
1 #include "IntelliHelper.h"
2 #include <algorithm>
3 #include <queue>
4 #include <cmath>
5 
6 
7 std::vector<Triangle> IntelliHelper::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 index;
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 = 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 Index bevor index in relation to the container length
38  auto getPrev = [](int index, int length){
39  return (index-1)>=0 ? (index-1) : (length-1);
40  };
41 
42  // get the vertex Index after index in relation to the container lenght
43  auto getPost = [](int index, int length){
44  return (index+1)%length;
45  };
46 
47  // return if the vertex is a tip
48  auto isTip = [](float angle){
49  return static_cast<double>(angle)<(M_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.index = 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.index, static_cast<int>(Vertices.size()));
76  int post = getPost(smallest.index, 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.index)].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.index);
86  for(size_t i=static_cast<size_t>(smallest.index); i<Vertices.size(); i++) {
87  Vertices[i].index-=1;
88  }
89 
90  // update post und prev index
91  post = post-1;
92  prev = prev<smallest.index ? 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 IntelliHelper::isInPolygon(std::vector<Triangle> &triangles, QPoint &point){
117  for(auto triangle : triangles) {
118  if(IntelliHelper::isInTriangle(triangle, point)) {
119  return true;
120  }
121  }
122  return false;
123 }
IntelliHelper::isInTriangle
bool isInTriangle(Triangle &tri, QPoint &P)
A function to check if a given point is in a triangle.
Definition: IntelliHelper.h:33
IntelliHelper.h
Triangle::B
QPoint B
Definition: IntelliHelper.h:11
Triangle::C
QPoint C
Definition: IntelliHelper.h:11
Triangle
The Triangle struct holds the 3 vertices of a triangle.
Definition: IntelliHelper.h:10
IntelliHelper::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: IntelliHelper.cpp:116
Triangle::A
QPoint A
Definition: IntelliHelper.h:11
IntelliHelper::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: IntelliHelper.cpp:7