File: point_location_utils.h

package info (click to toggle)
cgal 4.13-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 101,504 kB
  • sloc: cpp: 703,154; ansic: 163,044; sh: 674; fortran: 616; python: 411; makefile: 115
file content (150 lines) | stat: -rw-r--r-- 5,945 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <CGAL/Arr_point_location_result.h>

//-----------------------------------------------------------------------------
// Print the result of a point-location query.
//
#if CGAL_ARR_POINT_LOCATION_VERSION < 2
template <class Arrangement_2>
void print_point_location(const typename Arrangement_2::Point_2& q,
                          CGAL::Object    obj)
{
  typename Arrangement_2::Vertex_const_handle    v;
  typename Arrangement_2::Halfedge_const_handle  e;
  typename Arrangement_2::Face_const_handle      f;

  std::cout << "The point (" << q << ") is located ";
  if (CGAL::assign(f, obj))
  {
    // q is located inside a face:
    if (f->is_unbounded())
      std::cout << "inside the unbounded face." << std::endl;
    else
      std::cout << "inside a bounded face." << std::endl;
  }
  else if (CGAL::assign(e, obj))
  {
    // q is located on an edge:
    std::cout << "on an edge: " << e->curve() << std::endl;
  }
  else if (CGAL::assign(v, obj))
  {
    // q is located on a vertex:
    if (v->is_isolated())
      std::cout << "on an isolated vertex: " << v->point() << std::endl;
    else
      std::cout << "on a vertex: " << v->point() << std::endl;
  }
  else
  {
    CGAL_error_msg( "Invalid object.");
  }
}
#else
template <typename Arrangement_2>
void
print_point_location
(const typename Arrangement_2::Point_2& q,
 typename CGAL::Arr_point_location_result<Arrangement_2>::Type obj)
{
  typedef typename Arrangement_2::Vertex_const_handle   Vertex_const_handle;
  typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
  typedef typename Arrangement_2::Face_const_handle     Face_const_handle;

  const Vertex_const_handle*   v;
  const Halfedge_const_handle* e;
  const Face_const_handle*     f;
  
  std::cout << "The point (" << q << ") is located ";
  if ( ( f = boost::get<Face_const_handle>(&obj) ) )          // located inside a face
    std::cout << "inside "
              << (((*f)->is_unbounded()) ? "the unbounded" : "a bounded")
              << " face." << std::endl;
  else if ( ( e = boost::get<Halfedge_const_handle>(&obj) ) ) // located on an edge
    std::cout << "on an edge: " << (*e)->curve() << std::endl;
  else if ( ( v = boost::get<Vertex_const_handle>(&obj) ) )   // located on a vertex
    std::cout << "on " << (((*v)->is_isolated()) ? "an isolated" : "a")
              << " vertex: " << (*v)->point() << std::endl;
  else CGAL_error_msg("Invalid object.");
}
#endif

//-----------------------------------------------------------------------------
// Perform a point-location query and print the result.
//
template <class PointLocation>
void point_location_query(const PointLocation& pl,
                          const typename
                          PointLocation::Arrangement_2::Point_2& q)
{
  // Perform the point-location query.
  typedef PointLocation                                 Point_location;
  typedef typename Point_location::Arrangement_2        Arrangement_2;
  typename CGAL::Arr_point_location_result<Arrangement_2>::Type obj =
    pl.locate(q);

  // Print the result.
  print_point_location<Arrangement_2>(q, obj);
}

//-----------------------------------------------------------------------------
// Perform a vertical ray-shooting query and print the result.
//
template <class VerticalRayShoot>
void vertical_ray_shooting_query(const VerticalRayShoot& vrs,
                                 const typename
                                 VerticalRayShoot::Arrangement_2::Point_2& q)
{
  typedef VerticalRayShoot                                      Vertical_ray_shooting;

  // Perform the point-location query.
  typename Vertical_ray_shooting::result_type obj = vrs.ray_shoot_up(q);
  
  // Print the result.
  typedef typename Vertical_ray_shooting::Arrangement_2 Arrangement_2;
  typedef typename Arrangement_2::Vertex_const_handle   Vertex_const_handle;
  typedef typename Arrangement_2::Halfedge_const_handle Halfedge_const_handle;
  typedef typename Arrangement_2::Face_const_handle     Face_const_handle;

  const Vertex_const_handle*   v;
  const Halfedge_const_handle* e;
  const Face_const_handle*     f;
  
  std::cout << "Shooting up from (" << q << ") : ";

  if ( (v = boost::get<Vertex_const_handle>(&obj)) )         // we hit a vertex
    std::cout << "hit " << (((*v)->is_isolated()) ? "an isolated" : "a")
              << " vertex: " << (*v)->point() << std::endl;
  else if ( (e = boost::get<Halfedge_const_handle>(&obj)) )  // we hit an edge
    std::cout << "hit an edge: " << (*e)->curve() << std::endl;
  else if ( (f = boost::get<Face_const_handle>(&obj)) ) {    // we hit nothing
    CGAL_assertion((*f)->is_unbounded());
    std::cout << "hit nothing." << std::endl;
  }
  else CGAL_error_msg("Invalid object.");
}

//-----------------------------------------------------------------------------
// Construct the arrangement of segments needed for the point-location and
// the vertical ray-shooting examples.
// The function assumes that the arrangement is of line segments with integer
// coordinates.
//			
template <class Arrangement_>
void construct_segments_arr(Arrangement_& arr)
{
  typedef Arrangement_                                Arrangement_2;
  typedef typename Arrangement_2::Point_2             Point_2;
  typedef typename Arrangement_2::X_monotone_curve_2  Segment_2;
  typedef typename Arrangement_2::Halfedge_handle     Halfedge_handle;

  Point_2    p0(3,2), p1(0,3), p2(2,5), p3(4,5), p4(6,3), p5(3,0);
  Segment_2  s1(p1, p2), s2(p2, p3), s3(p3, p4), s4(p4, p5), s5(p5, p1);

  arr.insert_in_face_interior(p0, arr.unbounded_face());

  Halfedge_handle e1 = arr.insert_in_face_interior(s1, arr.unbounded_face());
  Halfedge_handle e2 = arr.insert_from_left_vertex(s2, e1->target());
  Halfedge_handle e3 = arr.insert_from_left_vertex(s3, e2->target());
  Halfedge_handle e4 = arr.insert_from_right_vertex(s4, e3->target());
  arr.insert_at_vertices(s5, e4->target(), e1->source());
}