Parasol Planning Library (PPL)
MedialAxis2D.h
Go to the documentation of this file.
1 #ifndef MEDIAL_AXIS_2D_H_
2 #define MEDIAL_AXIS_2D_H_
3 
4 #include <memory>
5 #include <map>
6 #include <limits>
7 #include <algorithm>
8 #include <unordered_map>
9 #include <tuple>
10 #include <CGAL/Simple_cartesian.h>
11 #include <CGAL/Segment_Delaunay_graph_filtered_traits_2.h>
12 #include <CGAL/Segment_Delaunay_graph_2.h>
13 #include <CGAL/Triangulation_2.h>
14 #include <containers/sequential/graph/graph.h>
15 #include <containers/sequential/graph/algorithms/graph_algo_util.h>
16 #include <boost/functional/hash.hpp>
17 
18 using namespace std;
19 
20 #include "Vector.h"
21 using namespace mathtool;
22 #include "IOUtils.h"
23 
24 #include "Geometry/GMSPolyhedron.h"
26 #include "SegmentTrees.h"
28 
29 
30 
34 class MedialAxis2D {
35 
36  public:
39  typedef CGAL::Simple_cartesian<double> CK;
40  typedef CGAL::Segment_Delaunay_graph_filtered_traits_2<CK,
41  CGAL::Field_with_sqrt_tag> Gt;
42  typedef CGAL::Segment_Delaunay_graph_2<Gt> SDG2;
43  typedef typename SDG2::Site_2 Site2;
44  typedef typename SDG2::Point_2 Point2;
45  typedef typename SDG2::Edge Edge2;
46  typedef typename SDG2::Data_structure DS;
47  typedef typename Gt::Segment_2 Segment2;
48  typedef CGAL::Parabola_segment_2<Gt> Parabola2;
49  // Type for clearance info - first: clearance value, second: witness
50  typedef pair<double,Point3d> ClearanceType;
51  // Types for skeleton and its annotations
53  typedef unordered_map<WorkspaceSkeleton::VD, ClearanceType>
55 
57  struct MedialEdge {
59  MedialEdge(Segment2& _s, Site2& _s1, Site2& _s2, double _ss = 0);
60  MedialEdge(Parabola2& _p, Point2& _s, Point2& _t, Site2& _s1,
61  Site2& _s2);
62  MedialEdge(Point2& _s, Point2& _t, Site2& _s1, Site2& _s2);
63 
65  const Point2& GetSource() { return m_interpolated.front(); }
66  const Point2& GetTarget() { return m_interpolated.back(); }
67  bool IsSegment() { return m_isLine; }
68 
70  void InterpolateSegment(double _step);
71 
72  vector<Point2> m_interpolated;
74  Site2 m_site1, m_site2;
75  bool m_isLine{true};
76  bool m_isFree{false};
77  friend class MedialAxis2D;
78  };
79 
81  typedef stapl::sequential::graph<stapl::UNDIRECTED,stapl::MULTIEDGES,
83 
86  struct PolygonSegment {
87  // Constructor function
88  PolygonSegment(Point2& _s, Point2& _t);
89  // Check the point lies on the segment
90  bool OnLine(const Point2& _p);
91  Point2 Source() { return m_end[0]; }
92  Point2 Target() { return m_end[1]; }
93  double GetConstant() { return m_constant; }
94  double GetMultiple() { return m_multiple; }
95  Point2 m_end[2];
96  double m_constant;
97  double m_multiple;
98  };
99  typedef vector<PolygonSegment> PolygonSegments;
100 
101  struct edgeHash {
102  size_t operator()(const WorkspaceSkeleton::ED& _ed) const {
103  size_t seed = 0;
104  boost::hash_combine(seed,_ed.id());
105  boost::hash_combine(seed,boost::hash_value(make_pair(_ed.source(),
106  _ed.target())));
107  return seed;
108  //return hash<typename ED::edge_id_type>()(_ed.id());
109  }
110  };
111  // Clearance map type for skeleton edges
112  typedef unordered_map<WorkspaceSkeleton::ED,vector<ClearanceType>,
117 
118  MedialAxis2D() : m_segTree(2){}
119  MedialAxis2D(vector<GMSPolyhedron>& _polys, const Boundary* _b,
120  vector<Boundary*> _bndrys=vector<Boundary*>());
121 
125 
128  void AddSegments(vector<pair<Point3d,Point3d>>& _s);
129 
133  void AddSegments(vector<Point3d>& _p, vector<pair<size_t,size_t>>& _s);
134 
137  void AddPoints(vector<Point3d>& _p);
138 
140  void BuildMedialAxis();
141 
145 
149  tuple<WorkspaceSkeleton,VertexClearanceMapType,EdgeClearanceMapType>
150  GetSkeleton(size_t _t=0);
151 
153  vector<ClearanceType> AnnotateSegment(MedialEdge& _e);
154 
155  double GetVertexClearance(size_t _i);
156  Point3d GetVertexClearanceWitness(size_t _i);
157 
159 
160  private:
163 
165  void AddPolygon(const GMSPolyhedron& _p,
166  vector<pair<Point3d,Point3d>>& _s, Boundary* _b = nullptr);
167 
169  bool IsSkeletonEdge(Edge2& _e);
170 
172  bool IsMedialAxisEdge(Edge2& _e, bool k=false);
174  bool IsReflexBisector(const Point2& _p1, const Point2& _p2,
175  Site2& _s1, Site2& _s2);
176 
178  ClearanceType GetMinDistance(const Point2& _p, Site2& _s1, Site2& _s2);
179 
181  ClearanceType DistanceToSite(const Point2& _p, Site2& _s);
182 
184  double GetMinDistance(MedialEdge& _e);
185 
187  double GetMaxDistance(MedialEdge& _e);
188 
190  void CalculateClearance();
192  bool IsFree(const Point2& _p);
194  bool IsOutside(const Point2& _p);
195 
197  void ValidateEdge(MedialEdge& _e);
198 
202  Point2 MidPoint(Site2& _o, Site2& _p, Site2& _q, Point2& _fp);
203 
207 
208  SDG2 sdg;
209  MedialAxisGraph m_graph;
210  vector<PolygonSegments> m_polygons;
211 
212  SegmentTrees<> m_segTree;
213 
214  unordered_map<size_t, ClearanceType> m_vertexClearance;
215 
216  bool m_debug{false};
217  Point3d m_boundary[2];
218 
220 };
221 
222 #endif
Definition: Boundary.h:30
Definition: GMSPolyhedron.h:42
2D Medial Axis construction using Segment Delaunay Graph
Definition: MedialAxis2D.h:34
pair< double, Point3d > ClearanceType
Definition: MedialAxis2D.h:50
CGAL::Simple_cartesian< double > CK
Definition: MedialAxis2D.h:39
MedialAxis2D()
Definition: MedialAxis2D.h:118
Gt::Segment_2 Segment2
Definition: MedialAxis2D.h:47
SDG2::Site_2 Site2
Definition: MedialAxis2D.h:43
CGAL::Parabola_segment_2< Gt > Parabola2
Definition: MedialAxis2D.h:48
CGAL::Segment_Delaunay_graph_filtered_traits_2< CK, CGAL::Field_with_sqrt_tag > Gt
Definition: MedialAxis2D.h:41
SDG2::Data_structure DS
Definition: MedialAxis2D.h:46
SDG2::Edge Edge2
Definition: MedialAxis2D.h:45
unordered_map< WorkspaceSkeleton::VD, ClearanceType > VertexClearanceMapType
Definition: MedialAxis2D.h:54
stapl::sequential::graph< stapl::UNDIRECTED, stapl::MULTIEDGES, Point2, MedialEdge > MedialAxisGraph
Underlying medial axis graph type.
Definition: MedialAxis2D.h:82
unordered_map< WorkspaceSkeleton::ED, vector< ClearanceType >, edgeHash > EdgeClearanceMapType
Definition: MedialAxis2D.h:113
SDG2::Point_2 Point2
Definition: MedialAxis2D.h:44
CGAL::Segment_Delaunay_graph_2< Gt > SDG2
Definition: MedialAxis2D.h:42
vector< PolygonSegment > PolygonSegments
Definition: MedialAxis2D.h:99
WorkspaceSkeleton SkeletonGraphType
Definition: MedialAxis2D.h:52
Definition: SegmentTrees.h:25
Geometric skeleton of the workspace.
Definition: WorkspaceSkeleton.h:22
BaseType::EID ED
Definition: WorkspaceSkeleton.h:32
Definition: Cfg.h:23
Medial axis edge structure.
Definition: MedialAxis2D.h:57
vector< Point2 > m_interpolated
Definition: MedialAxis2D.h:72
const Point2 & GetSource()
One line accessors.
Definition: MedialAxis2D.h:65
const Point2 & GetTarget()
Definition: MedialAxis2D.h:66
Site2 m_site1
approximating edge
Definition: MedialAxis2D.h:74
bool IsSegment()
Definition: MedialAxis2D.h:67
Definition: MedialAxis2D.h:86
Point2 Target()
Definition: MedialAxis2D.h:92
double GetMultiple()
Definition: MedialAxis2D.h:94
double m_multiple
Multiple for the line equation.
Definition: MedialAxis2D.h:97
Point2 Source()
Definition: MedialAxis2D.h:91
double GetConstant()
Definition: MedialAxis2D.h:93
double m_constant
Constant for the line equation.
Definition: MedialAxis2D.h:96
Definition: MedialAxis2D.h:101
size_t operator()(const WorkspaceSkeleton::ED &_ed) const
Definition: MedialAxis2D.h:102