1 // Copyright (c) 2003, 2017  INRIA Sophia-Antipolis (France).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Interpolation/include/CGAL/Voronoi_intersection_2_traits_3.h $
7 // $Id: Voronoi_intersection_2_traits_3.h 254d60f 2019-10-19T15:23:19+02:00 Sébastien Loriot
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 // Author(s)     : Julia Floetotto, Mael Rouxel-Labbé
11 
12 #ifndef CGAL_VORONOI_INTERSECTION_2_TRAITS_3_H
13 #define CGAL_VORONOI_INTERSECTION_2_TRAITS_3_H
14 
15 #include <CGAL/license/Interpolation.h>
16 
17 #include <CGAL/Origin.h>
18 #include <CGAL/tags.h>
19 #include <CGAL/number_utils.h>
20 #include <CGAL/double.h>
21 #include <CGAL/number_utils_classes.h>
22 #include <CGAL/Algebraic_structure_traits.h>
23 #include <CGAL/predicates/predicates_for_voronoi_intersection_cartesian_2_3.h>
24 #include <CGAL/constructions/constructions_for_voronoi_intersection_cartesian_2_3.h>
25 #include <CGAL/function_objects.h>
26 #include <CGAL/representation_tags.h>
27 
28 namespace CGAL {
29 
30 template <class Traits>
31 class Orientation_with_normal_plane_2_3
32 {
33 public:
34   typedef typename Traits::Point_3     Point;
35   typedef typename Traits::Vector_3    Vector;
36 
37   typedef Orientation                  result_type;
38 
Orientation_with_normal_plane_2_3(const Vector & _normal,const Traits & _traits)39   Orientation_with_normal_plane_2_3(const Vector& _normal, const Traits& _traits)
40     : normal(_normal), traits(_traits)
41   { }
42 
operator()43   Orientation operator()(const Point& p, const Point& q, const Point& r) const
44   {
45     return traits.orientation_3_object()(p,q,q+normal,r);
46   }
47 
48 public:
49   const Vector& normal;
50   const Traits& traits;
51 };
52 
53 template < typename K >
54 class Side_of_plane_centered_sphere_2_3
55 {
56 public:
57   typedef typename K::Point_3               Point;
58   typedef typename K::Weighted_point_3      Weighted_point;
59   typedef typename K::Vector_3              Vector;
60   typedef typename K::Plane_3               Plane;
61   typedef typename K::Direction_3           Direction;
62 
63   typedef Oriented_side                     result_type;
64 
Side_of_plane_centered_sphere_2_3(const Point & _a,const Vector & _normal)65   Side_of_plane_centered_sphere_2_3(const Point& _a, const Vector& _normal)
66     : a(_a), normal(_normal)
67   { }
68 
operator()69   Oriented_side operator()(const Weighted_point& p, const Weighted_point& q,
70                            const Weighted_point& r, const Weighted_point& t) const
71   {
72     return side_of_plane_centered_sphere(a,normal,p,q,r,t);
73   }
74 
operator()75   Oriented_side operator()(const Weighted_point& p, const Weighted_point& q,
76                            const Weighted_point& r) const
77   {
78     return side_of_plane_centered_sphere(a,normal,p,q,r);
79   }
80 
operator()81   Oriented_side operator()(const Weighted_point& p, const Weighted_point& q) const
82   {
83     return side_of_plane_centered_sphere(a,normal,p,q);
84   }
85 
86 private:
87   const Point&   a;
88   const Vector&  normal;
89 };
90 
91 template < typename K >
92 class Construct_plane_centered_circumcenter_3
93 {
94 public:
95   typedef typename K::Point_3               Point;
96   typedef typename K::Weighted_point_3      Weighted_point;
97   typedef typename K::Vector_3              Vector;
98 
99   typedef Point                             result_type;
100 
Construct_plane_centered_circumcenter_3(const Point & _a,const Vector & _normal)101   Construct_plane_centered_circumcenter_3(const Point& _a, const Vector& _normal)
102     : a(_a), normal(_normal)
103   { }
104 
operator()105   Point operator()(const Weighted_point& p, const Weighted_point& q,
106                    const Weighted_point& r) const
107   {
108     return plane_centered_circumcenter_3(a,normal,p,q,r);
109   }
110 
111 private:
112   const Point&  a;
113   const Vector& normal;
114 };
115 
116 template < typename K >
117 class Construct_plane_intersected_bisector_3
118 {
119 public:
120   typedef typename K::Point_3             Point;
121   typedef typename K::Weighted_point_3    Weighted_point;
122   typedef typename K::Vector_3            Vector;
123   typedef typename K::Line_3              Line;
124 
125   typedef Line                            result_type;
126 
Construct_plane_intersected_bisector_3(const Point & _a,const Vector & _normal)127   Construct_plane_intersected_bisector_3(const Point& _a, const Vector& _normal)
128     : a(_a), normal(_normal)
129   { }
130 
operator()131   Line operator()(const Weighted_point& p, const Weighted_point& q) const
132   {
133     return plane_intersected_bisector_3(a, normal, p, q);
134   }
135 
136 private:
137   const Point&  a;
138   const Vector& normal;
139 };
140 
141 template < typename K >
142 class Compare_first_projection_3
143 {
144   //compares the projection of two points onto a second (non-trivial)
145   // vector in the projection plane:
146 public:
147   typedef typename K::Point_3      Point;
148   typedef typename K::Vector_3     Vector;
149   typedef typename K::FT           Coord_type;
150 
151   typedef Comparison_result        result_type;
152 
Compare_first_projection_3(const Vector & _normal)153   Compare_first_projection_3(const Vector& _normal) : normal(_normal) { }
154 
operator()155   Comparison_result operator()(const Point& p, const Point& q) const
156   {
157     if(normal.x() != Coord_type(0))
158       return (Comparison_result) CGAL_NTS
159           sign(Vector(normal.y(), -normal.x(), Coord_type(0))*(p-q));
160     if(normal.y() != Coord_type(0))
161       return (Comparison_result) CGAL_NTS
162           sign(Vector(-normal.y(), normal.x(), Coord_type(0))*(p-q));
163 
164     CGAL_assertion(normal.z() != Coord_type(0));
165     return (Comparison_result) CGAL_NTS
166         sign(Vector(-normal.z(), Coord_type(0), normal.x())*(p-q));
167   }
168 
169 private:
170   const Vector& normal;
171 };
172 
173 template < typename K >
174 class Compare_second_projection_3
175 {
176   //compares the projection of two points onto a second (non-trivial)
177   // vector in the projection plane:
178 public:
179   typedef typename K::FT           Coord_type;
180   typedef typename K::Vector_3     Vector;
181   typedef typename K::Point_3      Point;
182 
183   typedef Comparison_result        result_type;
184 
Compare_second_projection_3(const Vector & _normal)185   Compare_second_projection_3(const Vector& _normal) : normal(_normal) { }
186 
operator()187   Comparison_result operator()(const Point& p, const Point& q) const
188   {
189     if(normal.x() != Coord_type(0))
190       return (Comparison_result) CGAL_NTS
191           sign(Vector(normal.z(), Coord_type(0), -normal.x())*(p-q));
192     if(normal.y() != Coord_type(0))
193       return (Comparison_result) CGAL_NTS
194           sign(Vector(Coord_type(0), normal.z(), -normal.y())*(p-q));
195 
196     CGAL_assertion(normal.z() != Coord_type(0));
197     return (Comparison_result) CGAL_NTS
198         sign(Vector(Coord_type(0), -normal.z(), normal.y())*(p-q));
199   }
200 
201 private:
202   const Vector& normal;
203 };
204 
205 namespace Interpolation {
206 
207 template < typename K >
208 class Compute_area_3
209 {
210   //squareroot of compute_squared_area_3:
211   //-> if no sqrt is supported, cast to double
212 public:
213   typedef typename K::FT                       FT;
214   typedef typename K::Point_3                  Point;
215   typedef typename K::Compute_squared_area_3   Compute_squared_area;
216 
217   typedef FT                                   result_type;
218 
operator()219   FT operator()(const Point& p, const Point& q, const Point& r) const
220   {
221     typedef typename CGAL::Algebraic_structure_traits<FT> AST;
222     FT squared_area = Compute_squared_area()(p,q,r);
223     return cast_sqrt_to_double(squared_area, typename AST::Algebraic_category());
224   }
225 
226 private:
cast_sqrt_to_double(const FT & squared_area,Field_with_sqrt_tag)227   FT cast_sqrt_to_double(const FT& squared_area, Field_with_sqrt_tag) const
228   {
229     return CGAL_NTS sqrt(squared_area);
230   }
231 
cast_sqrt_to_double(const FT & squared_area,Integral_domain_without_division_tag)232   FT cast_sqrt_to_double(const FT& squared_area, Integral_domain_without_division_tag) const
233   {
234     double approx = CGAL_NTS to_double(squared_area);
235     return CGAL_NTS sqrt(approx);
236   }
237 };
238 
239 } // namespace Interpolation
240 
241 template < class K_ >
242 class Voronoi_intersection_2_traits_3
243   : public K_
244 {
245   typedef K_                                        Base;
246 
247 public:
248   typedef K_                                        Rep;
249 
250   //the regular triangulation traits model:
251   //Traits::Point_2 is a 3D point!!
252   typedef typename Rep::Point_3                     Point_2;
253   typedef typename Rep::Weighted_point_3            Weighted_point_2;
254 
255   //other types needed:
256   typedef typename Rep::Segment_3                   Segment_2;
257   typedef typename Rep::Triangle_3                  Triangle_2;
258   typedef typename Rep::Line_3                      Line_2;
259   typedef typename Rep::Ray_3                       Ray_2;
260   typedef typename Rep::Vector_3                    Vector_2;
261   typedef typename Rep::Circle_3                    Circle_2;
262 
263   typedef typename Rep::Construct_point_3           Construct_point_2;
264   typedef typename Rep::Construct_weighted_point_3  Construct_weighted_point_2;
265   typedef typename Rep::Construct_segment_3         Construct_segment_2;
266   typedef typename Rep::Construct_vector_3          Construct_vector_2;
267   typedef typename Rep::Construct_ray_3             Construct_ray_2;
268   typedef typename Rep::Construct_triangle_3        Construct_triangle_2;
269 
270   typedef typename Rep::Equal_3                     Equal_2;
271   typedef typename Rep::Construct_circumcenter_3    Construct_circumcenter_2;
272 
273   typedef typename Rep::Compare_distance_3          Compare_distance_2;
274   //if no sqrt is supported, it casts to double:
275   typedef Interpolation::Compute_area_3<Rep>        Compute_area_2;
276 
277   //specific tests:
278   typedef Orientation_with_normal_plane_2_3<Rep>    Orientation_2;
279   typedef Side_of_plane_centered_sphere_2_3<Rep>    Power_side_of_oriented_power_circle_2;
280 
281   typedef Construct_plane_centered_circumcenter_3<Rep> Construct_weighted_circumcenter_2;
282   typedef Construct_plane_intersected_bisector_3<Rep>  Construct_radical_axis_2;
283 
284   typedef Compare_first_projection_3<Rep>           Compare_x_2;
285   typedef Compare_second_projection_3<Rep>          Compare_y_2;
286 
287   typedef Compare_to_less<Compare_x_2>              Less_x_2;
288   typedef Compare_to_less<Compare_y_2>              Less_y_2;
289 
290   //for certificated coordinate/neighbor computation:
291   typedef typename Rep::Less_distance_to_point_3    Less_distance_to_point_2;
292   typedef typename Rep::Compute_squared_distance_3  Compute_squared_distance_2;
293 
294   //instantiations and creation of functors:
295   //for the triangulation:
296   Orientation_2
orientation_2_object()297   orientation_2_object() const
298   { return Orientation_2(normal, static_cast<const Base&>(*this)); }
299 
300   Power_side_of_oriented_power_circle_2
power_side_of_oriented_power_circle_2_object()301   power_side_of_oriented_power_circle_2_object() const
302   { return Power_side_of_oriented_power_circle_2(a, normal); }
303 
compare_distance_2_object()304   Compare_distance_2 compare_distance_2_object() const
305   { return this->K_::compare_distance_3_object(); }
306 
307   Compare_x_2
compare_x_2_object()308   compare_x_2_object() const
309   { return Compare_x_2(normal); }
310 
311   Compare_y_2
compare_y_2_object()312   compare_y_2_object() const
313   { return Compare_y_2(normal); }
314 
315   Less_x_2
less_x_2_object()316   less_x_2_object() const
317   { return compare_to_less(compare_x_2_object()); }
318 
319   Less_y_2
less_y_2_object()320   less_y_2_object() const
321   { return compare_to_less(compare_y_2_object()); }
322 
323   //for the coordinate computation:
compute_area_2_object()324   Compute_area_2 compute_area_2_object() const
325   { return Compute_area_2(); }
326 
327   //for constructions of dual:
328   Construct_weighted_circumcenter_2
construct_weighted_circumcenter_2_object()329   construct_weighted_circumcenter_2_object() const
330   { return Construct_weighted_circumcenter_2(a, normal); }
331 
construct_radical_axis_2_object()332   Construct_radical_axis_2 construct_radical_axis_2_object() const
333   { return Construct_radical_axis_2(a, normal); }
334 
construct_ray_2_object()335   Construct_ray_2 construct_ray_2_object() const
336   { return this->Base::construct_ray_3_object(); }
337 
construct_segment_2_object()338   Construct_segment_2 construct_segment_2_object() const
339   { return this->Base::construct_segment_3_object(); }
340 
construct_triangle_2_object()341   Construct_triangle_2 construct_triangle_2_object() const
342   { return this->Base::construct_triangle_3_object(); }
343 
344   //for certification of coordinate/neighbor computation:
less_distance_to_point_2_object()345   Less_distance_to_point_2 less_distance_to_point_2_object() const
346   { return this->Base::less_distance_to_point_3_object(); }
347 
compute_squared_distance_2_object()348   Compute_squared_distance_2 compute_squared_distance_2_object() const
349   { return this->Base::compute_squared_distance_3_object(); }
350 
351   //for compilation
construct_point_2_object()352   Construct_point_2 construct_point_2_object() const
353   { return this->Base::construct_point_3_object(); }
354 
construct_weighted_point_2_object()355   Construct_weighted_point_2 construct_weighted_point_2_object() const
356   { return this->Base::construct_weighted_point_3_object(); }
357 
equal_2_object()358   Equal_2 equal_2_object() const
359   { return this->Base::equal_3_object(); }
360 
construct_vector_2_object()361   Construct_vector_2 construct_vector_2_object() const
362   { return this->Base::construct_vector_3_object(); }
363 
construct_circumcenter_2_object()364   Construct_circumcenter_2 construct_circumcenter_2_object() const
365   { return this->Base::construct_circumcenter_3_object(); }
366 
367   //construction
368   Voronoi_intersection_2_traits_3(const Point_2& _a = Point_2(),
369                                   const Vector_2& _normal = NULL_VECTOR,
370                                   const K_& k = K_())
Base(k)371     : Base(k), a(_a), normal(_normal)
372   { }
373 
get_normal()374   const Vector_2& get_normal() const { return normal; }
get_point()375   const Point_2& get_point() const { return a; }
376 
377 public:
378   //defining the intersection plane:
379   const Point_2 a;
380   const Vector_2 normal;
381 };
382 
383 //put the homogeneous or cartesian tag
384 template < class Point, class Weighted_point, class Vector >
385 inline
386 Oriented_side
side_of_plane_centered_sphere(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r,const Weighted_point & t)387 side_of_plane_centered_sphere(const Point& a, const Vector& n, /*defines the plane*/
388                               const Weighted_point& p, const Weighted_point& q,
389                               const Weighted_point& r, const Weighted_point& t)
390 {
391   typedef typename Point::R::Rep_tag Tag;
392   return side_of_plane_centered_sphere(a,n,p,q,r,t, Tag());
393 }
394 
395 template < class Point, class Weighted_point, class Vector >
396 inline
397 Oriented_side
side_of_plane_centered_sphere(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r)398 side_of_plane_centered_sphere(const Point& a, const Vector& n, /*defines the plane*/
399                               const Weighted_point& p, const Weighted_point& q,
400                               const Weighted_point& r)
401 {
402   typedef typename Point::R::Rep_tag Tag;
403   return side_of_plane_centered_sphere(a,n,p,q,r,Tag());
404 }
405 
406 template < class Point, class Weighted_point, class Vector >
407 inline
408 Oriented_side
side_of_plane_centered_sphere(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q)409 side_of_plane_centered_sphere(const Point& a, const Vector& n, /*defines the plane*/
410                               const Weighted_point& p, const Weighted_point& q)
411 {
412   typedef typename Point::R::RT    RT;
413 
414   Comparison_result r =
415     Compare<RT>()(-CGAL_NTS square(  (p.x() - a.x()) * n.x() // Vector(a,p) * n
416                                    + (p.y() - a.y()) * n.y()
417                                    + (p.z() - a.z()) * n.z()),
418                   -CGAL_NTS square(  (q.x() - a.x()) * n.x() // Vector(a,q) * n
419                                    + (q.y() - a.y()) * n.y()
420                                    + (q.z() - a.z()) * n.z()));
421 
422   if(r == LARGER)
423     return ON_NEGATIVE_SIDE;
424   else if(r == SMALLER)
425     return ON_POSITIVE_SIDE;
426   return ON_ORIENTED_BOUNDARY;
427 }
428 
429 template < class Point, class Weighted_point, class Vector >
430 inline
431 Point
plane_centered_circumcenter_3(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r)432 plane_centered_circumcenter_3(const Point& a, const Vector& n, /*defines the plane*/
433                               const Weighted_point& p, const Weighted_point& q,
434                               const Weighted_point& r)
435 {
436   typedef typename Point::R::Rep_tag Tag;
437   return plane_centered_circumcenter_3(a,n,p,q,r, Tag());
438 }
439 
440 template < class Point, class Weighted_point, class Vector >
441 inline
442 typename Point::R::Line_3
plane_intersected_bisector_3(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q)443 plane_intersected_bisector_3(const Point& a, const Vector& n, /*defines the plane*/
444                              const Weighted_point& p, const Weighted_point& q)
445 {
446   typedef typename Point::R::Rep_tag Tag;
447   return plane_intersected_bisector_3(a,n,p,q, Tag());
448 }
449 
450 ///-----------------------------------------------------------
451 // Cartesian variants:
452 //
453 template < class Point, class Weighted_point, class Vector>
454 inline
455 Oriented_side
side_of_plane_centered_sphere(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r,const Weighted_point & t,Cartesian_tag)456 side_of_plane_centered_sphere(const Point& a, const Vector& n, /*defines the plane*/
457                               const Weighted_point& p, const Weighted_point& q,
458                               const Weighted_point& r, const Weighted_point& t,
459                               Cartesian_tag)
460 {
461   return side_of_plane_centered_sphereC3(a.x(), a.y(), a.z(),
462                                          n.x(), n.y(), n.z(),
463                                          p.x(), p.y(), p.z(),
464                                          q.x(), q.y(), q.z(),
465                                          r.x(), r.y(), r.z(),
466                                          t.x(), t.y(), t.z());
467 }
468 
469 template < class Point, class Weighted_point, class Vector >
470 inline
471 Oriented_side
side_of_plane_centered_sphere(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r,Cartesian_tag)472 side_of_plane_centered_sphere(const Point& a, const Vector& n, /*defines the plane*/
473                               const Weighted_point& p, const Weighted_point& q,
474                               const Weighted_point& r,
475                               Cartesian_tag)
476 {
477   return side_of_plane_centered_sphereC3(a.x(), a.y(), a.z(),
478                                          n.x(), n.y(), n.z(),
479                                          p.x(), p.y(), p.z(),
480                                          q.x(), q.y(), q.z(),
481                                          r.x(), r.y(), r.z());
482 }
483 
484 template < class Point, class Weighted_point, class Vector >
485 inline
486 Point
plane_centered_circumcenter_3(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r,Cartesian_tag)487 plane_centered_circumcenter_3(const Point& a, const Vector& n, /*defines the plane*/
488                               const Weighted_point& p, const Weighted_point& q,
489                               const Weighted_point& r,
490                               Cartesian_tag)
491 {
492   typename Point::R::RT x,y,z;
493   plane_centered_circumcenterC3(a.x(), a.y(), a.z(),
494                                 n.x(), n.y(), n.z(),
495                                 p.x(), p.y(), p.z(),
496                                 q.x(), q.y(), q.z(),
497                                 r.x(), r.y(), r.z(),x,y,z);
498   return Point(x,y,z);
499 }
500 
501 template < class Point, class Weighted_point, class Vector>
502 inline
503 typename Point::R::Line_3
plane_intersected_bisector_3(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,Cartesian_tag)504 plane_intersected_bisector_3(const Point& a, const Vector& n, /*defines the plane*/
505                              const Weighted_point& p, const Weighted_point& q,
506                              Cartesian_tag)
507 {
508   typename Point::R::RT x1,y1,z1, x2,y2,z2;
509   typedef typename Point::R::Line_3 Line;
510   bisector_plane_intersectionC3(a.x(), a.y(), a.z(),
511                                 n.x(), n.y(), n.z(),
512                                 p.x(), p.y(), p.z(),
513                                 q.x(), q.y(), q.z(), x1,y1,z1,x2,y2,z2);
514 
515   return Line(Point(x1,y1,z1), Point(x2,y2,z2));
516 }
517 
518 // Homogeneous variants.
519 
520 // The 3 following call the cartesian version over FT, because an
521 // homogeneous special version has not yet been written.
522 
523 template <class Point, class Weighted_point, class Vector >
524 inline
525 Oriented_side
side_of_plane_centered_sphere(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r,const Weighted_point & t,Homogeneous_tag)526 side_of_plane_centered_sphere(const Point& a, const Vector& n, /*defines the plane*/
527                               const Weighted_point& p, const Weighted_point& q,
528                               const Weighted_point& r, const Weighted_point& t,
529                               Homogeneous_tag)
530 {
531   return side_of_plane_centered_sphereC3(a.x(), a.y(), a.z(),
532                                          n.x(), n.y(), n.z(),
533                                          p.x(), p.y(), p.z(),
534                                          q.x(), q.y(), q.z(),
535                                          r.x(), r.y(), r.z(),
536                                          t.x(), t.y(), t.z());
537 }
538 
539 template < class Point, class Weighted_point, class Vector >
540 inline
541 Oriented_side
side_of_plane_centered_sphere(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r,Homogeneous_tag)542 side_of_plane_centered_sphere(const Point& a, const Vector& n, /*defines the plane*/
543                               const Weighted_point& p, const Weighted_point& q,
544                               const Weighted_point& r,
545                               Homogeneous_tag)
546 {
547   return side_of_plane_centered_sphereC3(a.x(), a.y(), a.z(),
548                                          n.x(), n.y(), n.z(),
549                                          p.x(), p.y(), p.z(),
550                                          q.x(), q.y(), q.z(),
551                                          r.x(), r.y(), r.z());
552 }
553 
554 template < class Point, class Weighted_point, class Vector >
555 inline
556 Point
plane_centered_circumcenter_3(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,const Weighted_point & r,Homogeneous_tag)557 plane_centered_circumcenter_3(const Point& a, const Vector& n, /*defines the plane*/
558                               const Weighted_point& p, const Weighted_point& q,
559                               const Weighted_point& r,
560                               Homogeneous_tag)
561 {
562   typename Point::R::RT x,y,z;
563   plane_centered_circumcenterC3(a.x(), a.y(), a.z(),
564                                 n.x(), n.y(), n.z(),
565                                 p.x(), p.y(), p.z(),
566                                 q.x(), q.y(), q.z(),
567                                 r.x(), r.y(), r.z(),x,y,z);
568   return Point(x,y,z);
569 }
570 
571 template < class Point, class Weighted_point, class Vector >
572 inline
573 typename Point::R::Line_3
plane_intersected_bisector_3(const Point & a,const Vector & n,const Weighted_point & p,const Weighted_point & q,Homogeneous_tag)574 plane_intersected_bisector_3(const Point& a, const Vector& n, /*defines the plane*/
575                              const Weighted_point& p, const Weighted_point& q,
576                              Homogeneous_tag)
577 {
578   typename Point::R::RT x1,y1,z1, x2,y2,z2;
579   typedef typename Point::R::Line_3 Line;
580   bisector_plane_intersectionC3(a.x(), a.y(), a.z(),
581                                 n.x(), n.y(), n.z(),
582                                 p.x(), p.y(), p.z(),
583                                 q.x(), q.y(), q.z(),x1,y1,z1,x2,y2,z2);
584 
585   return Line(Point(x1,y1,z1), Point(x2,y2,z2));
586 }
587 
588 } //namespace CGAL
589 
590 #endif // CGAL_VORONOI_INTERSECTION_2_TRAITS_3_H
591