ConvexHull.cpp
1 #include <boost/foreach.hpp>
2 #include <cfloat>
3 #include "ConvexHull.hpp"
4 #include "geotests.hpp"
5 
6 using namespace std;
7 
8 namespace
9 {
10  Vector2D GetReflectedPoint(Edge const& edge,Vector2D const& point)
11  {
12  const Vector2D par(normalize(Parallel(edge)));
13  const Vector2D edge0=edge.vertices.first;
14  const Vector2D temp=point-edge0;
15  return 2*par*ScalarProd(par,temp)-temp+edge0;
16  }
17 
18  bool check_same_point(const vector<Vector2D>& vertices,
19  const Vector2D& p,
20  double tol)
21  {
22  BOOST_FOREACH(const Vector2D& v, vertices)
23  {
24  if(dist_sqr(v-p)<tol)
25  return true;
26  }
27  return false;
28  }
29 }
30 
31 void ConvexHull(vector<Vector2D> &result,Tessellation const& tess,int index)
32 {
33  vector<int> edge_index=tess.GetCellEdges(index);
34  const double eps=1e-30;
35  vector<Vector2D> points;
36  points.reserve(10);
37  double R=tess.GetWidth(index);
38  points.push_back(tess.GetEdge(edge_index[0]).vertices.first);
39  points.push_back(tess.GetEdge(edge_index[0]).vertices.second);
40  // Remove bad edges
41  for(size_t i=1;i<edge_index.size();++i)
42  {
43  const Edge& edge = tess.GetEdge(edge_index[i]);
44  if (edge.GetLength() < 1e-8 * R)
45  continue;
46  if(!check_same_point(points,edge.vertices.first,eps*pow(R,2)))
47  points.push_back(edge.vertices.first);
48  if(!check_same_point(points,edge.vertices.second,eps*pow(R,2)))
49  points.push_back(edge.vertices.second);
50  }
51 
52  const Vector2D cm = tess.GetCellCM(index);
53 
54  // Start building the convexhull
55  size_t n=points.size();
56  vector<double> angles(n);
57  for(size_t i=0;i<n;++i)
58  angles.at(i)=atan2(points.at(i).y-cm.y,points.at(i).x-cm.x);
59  const vector<size_t> indeces = sort_index(angles);
60  result = VectorValues(points,indeces);
61 }
62 
63 void ConvexHull(std::vector<std::pair<Vector2D, Vector2D> >& result, Tessellation const& tess, int index)
64 {
65  vector<int> edge_index = tess.GetCellEdges(index);
66  size_t Nedges = edge_index.size();
67  double R = 0.0;
68  double eps = 1e-8;
69  for (size_t i = 0; i < Nedges; ++i)
70  R = std::max(R, tess.GetEdge(edge_index[i]).GetLength());
71  // keep only good edges
72  std::vector<int> good_edges;
73  for (size_t i = 0; i < Nedges; ++i)
74  if (tess.GetEdge(edge_index[i]).GetLength() > R* eps)
75  good_edges.push_back(edge_index[i]);
76  Nedges = good_edges.size();
77  std::vector<double> angles(Nedges);
78  const Vector2D cm = tess.GetCellCM(index);
79  // sort by angle
80  for (size_t i = 0; i < Nedges; ++i)
81  {
82  Vector2D midpoint = 0.5 * (tess.GetEdge(good_edges[i]).vertices.first + tess.GetEdge(good_edges[i]).vertices.second) - cm;
83  angles[i] = atan2(midpoint.y, midpoint.x);
84  }
85  const vector<size_t> indeces = sort_index(angles);
86  result.resize(Nedges);
87  for (size_t i = 0; i < Nedges; ++i)
88  {
89  Edge const& edge = tess.GetEdge(good_edges[indeces[i]]);
90  // make sure in right order
91  if(orient2d(TripleConstRef<Vector2D>(edge.vertices.first, edge.vertices.second, cm)) > 0.0)
92  result[i] = std::pair<Vector2D, Vector2D>(edge.vertices.first, edge.vertices.second);
93  else
94  result[i] = std::pair<Vector2D, Vector2D>(edge.vertices.second, edge.vertices.first);
95  }
96 }
97 
98 void ConvexEdges(vector<int> &result,Tessellation const& tess,int index)
99 {
100  vector<int> const& edges=tess.GetCellEdges(index);
101  const Vector2D mypoint=tess.GetMeshPoint(index);
102  int nedges=static_cast<int>(edges.size());
103  result.resize(static_cast<size_t>(nedges));
104  vector<double> angles(static_cast<size_t>(nedges));
105  for(int i=0;i<nedges;++i)
106  {
107  Edge const& edge=tess.GetEdge(edges[static_cast<size_t>(i)]);
108  const int other=(edge.neighbors.first==index)? edge.neighbors.second : edge.neighbors.first;
109  Vector2D otherpoint=(other==-1) ? GetReflectedPoint(edge,mypoint) : tess.GetMeshPoint(other);
110  angles[static_cast<size_t>(i)]=atan2(otherpoint.y-mypoint.y,otherpoint.x-mypoint.x);
111  }
112  vector<int> temp;
113  sort_index(angles,temp);
114  for(size_t i=0;i<static_cast<size_t>(nedges);++i)
115  result[i]=edges[static_cast<size_t>(temp[i])];
116 }
vector< T > VectorValues(vector< T > const &v, vector< int > const &index)
Returns only the values with indeces in index.
Definition: utils.hpp:326
Various checks for geometric data.
void sort_index(const vector< T > &arr, vector< int > &res)
Returns the indeces of a sort.
Definition: utils.hpp:500
Vector2D Parallel(Edge const &edge)
Calculates a unit vector parallel to an edge.
Definition: Edge.cpp:83
Abstract class for tessellation.
virtual Vector2D const & GetCellCM(int index) const =0
Returns Position of Cell&#39;s CM.
Interface between two cells.
Definition: Edge.hpp:13
virtual Vector2D GetMeshPoint(int index) const =0
Returns Position of mesh generating point.
double max(vector< double > const &v)
returns the maximal term in a vector
Definition: utils.cpp:52
double y
Component in the y direction.
Definition: geometry.hpp:48
A collection of three identical references.
Definition: triplet.hpp:12
virtual Edge const & GetEdge(int index) const =0
Returns edge (interface between cells)
void ConvexHull(vector< Vector2D > &result, Tessellation const &tess, int index)
Returns the ConvexHull for a set of points.
Definition: ConvexHull.cpp:31
double ScalarProd(Vector3D const &v1, Vector3D const &v2)
Scalar product of two vectors.
Definition: Vector3D.cpp:185
std::pair< Vector2D, Vector2D > vertices
Points at the ends of the edge.
Definition: Edge.hpp:18
virtual double GetWidth(int index) const =0
Returns the effective width of a cell.
Vector2D normalize(const Vector2D &v)
Normalized a vector.
Definition: geometry.cpp:158
Calculates the convex hull from a set of points.
std::pair< int, int > neighbors
Neighboring cells.
Definition: Edge.hpp:21
virtual vector< int > const & GetCellEdges(int index) const =0
Returns the indexes of a cell&#39;s edges.
2D Mathematical vector
Definition: geometry.hpp:15
double GetLength(void) const
Returns the length of the edge.
Definition: Edge.cpp:26
double orient2d(const TripleConstRef< Vector2D > &points)
Checks whether 3 given points are on a counterclockwise circle, clockwise circle or colinear...
Definition: geotests.cpp:76
void ConvexEdges(vector< int > &result, Tessellation const &tess, int index)
Returns the ConvexHull of the edges of a cell.
Definition: ConvexHull.cpp:98
double x
Component in the x direction.
Definition: geometry.hpp:45
double dist_sqr(const Vector2D &v)
Calculates the square of the distance. This is computationaly cheaper then actually calculating the d...
Definition: geometry.cpp:163