From e8663963f20ce433d3e2f984a02239e56d4d474b Mon Sep 17 00:00:00 2001 From: Pedro Machado Manhaes de Castro Date: Thu, 17 Jul 2008 14:08:50 +0000 Subject: [PATCH] Constructing a Circle_3 passing through three points p, q, r --- .../include/CGAL/Cartesian/Circle_3.h | 21 ++++++++++++-- Kernel_23/include/CGAL/Circle_3.h | 3 ++ .../include/CGAL/Kernel/function_objects.h | 9 ++++++ .../include/CGAL/_test_cls_circle_3.h | 29 ++++++++++++++++++- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/Circle_3.h b/Cartesian_kernel/include/CGAL/Cartesian/Circle_3.h index 6f29467c6db..fe3c6b88ef5 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/Circle_3.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/Circle_3.h @@ -88,7 +88,8 @@ public: base = Rep(circle.diametral_sphere(), circle.supporting_plane()); else { assign(point, obj); - CircleC3(point, FT(0), Vector_3(FT(1),FT(0),FT(0))); + CircleC3 circle = CircleC3(point, FT(0), Vector_3(FT(1),FT(0),FT(0))); + base = Rep(circle.diametral_sphere(), circle.supporting_plane()); } } @@ -104,10 +105,26 @@ public: base = Rep(circle.diametral_sphere(), circle.supporting_plane()); else { assign(point, obj); - CircleC3(point, FT(0), Vector_3(FT(1),FT(0),FT(0))); + CircleC3 circle = CircleC3(point, FT(0), Vector_3(FT(1),FT(0),FT(0))); + base = Rep(circle.diametral_sphere(), circle.supporting_plane()); } } + CircleC3(const Point_3 &p, const Point_3 &q, const Point_3 &r) { + // p, q, r are not collinear + CGAL_kernel_precondition(!R().collinear_3_object()(p, q, r)); + Plane_3 p1 = R().construct_plane_3_object()(p, q, r); + Plane_3 p2 = R().construct_bisector_3_object()(p, q); + Plane_3 p3 = R().construct_bisector_3_object()(p, r); + Object obj = R().intersect_3_object()(p1, p2, p3); + // must be a point, otherwise they are collinear + Point_3 center; + assign(center, obj); + FT sqr = R().compute_squared_distance_3_object()(center, r); + Sphere_3 s = R().construct_sphere_3_object()(center, sqr); + base = Rep(s, p1); + } + const Plane_3& supporting_plane() const { return get(base).second; diff --git a/Kernel_23/include/CGAL/Circle_3.h b/Kernel_23/include/CGAL/Circle_3.h index 74fc18fea9f..1811b95e104 100644 --- a/Kernel_23/include/CGAL/Circle_3.h +++ b/Kernel_23/include/CGAL/Circle_3.h @@ -100,6 +100,9 @@ public: Circle_3(const Plane_3& p, const Sphere_3& s) : Rep(typename R::Construct_circle_3()(p,s)) {} + Circle_3(const Point_3& p1, const Point_3& p2, const Point_3& p3) + : Rep(typename R::Construct_circle_3()(p1,p2,p3)) {} + Circle_3(const Rep& r) : Rep(r) {} diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 4774e6a9b34..460df66c121 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -810,6 +810,11 @@ namespace CommonKernelFunctors { const Sphere_3& s, int a) const { return Rep(p, s, a); } + Rep + operator() (Return_base_tag, const Point_3& p1, + const Point_3& p2, const Point_3& p3) const + { return Rep(p1, p2, p3); } + Circle_3 operator()(const Point_3& p, const FT& sr, const Plane_3& plane) const @@ -844,6 +849,10 @@ namespace CommonKernelFunctors { Circle_3 operator() (const Sphere_3& s, const Plane_3& p, int a) const { return this->operator()(Return_base_tag(), p, s, a); } + + Circle_3 + operator()( const Point_3& p1, const Point_3& p2, const Point_3& p3) const + { return this->operator()(Return_base_tag(), p1, p2, p3); } }; diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_circle_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_circle_3.h index 22f02c568ce..9cf8d710d52 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_circle_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_circle_3.h @@ -82,9 +82,13 @@ void _test_circle_construct(const K &k) { typedef typename K::Vector_3 Vector_3; typedef typename K::Equal_3 Equal_3; typedef typename K::Construct_circle_3 Construct_circle_3; + typedef typename K::Compute_squared_distance_3 Compute_squared_distance_3; + typedef typename K::Collinear_3 Collinear_3; Equal_3 theEqual_3 = k.equal_3_object(); Construct_circle_3 theConstruct_circle_3 = k.construct_circle_3_object(); + Compute_squared_distance_3 squared_distance = k.compute_squared_distance_3_object(); + Collinear_3 collinear = k.collinear_3_object(); CGAL::Random generatorOfgenerator; int random_seed = generatorOfgenerator.get_int(0, 123456); @@ -138,7 +142,30 @@ void _test_circle_construct(const K &k) { Circle_3 circle3 = theConstruct_circle_3(p,sqr,Vector_3(a,b,c)); assert(theEqual_3(circle,circle2)); assert(theEqual_3(circle,circle3)); - } + } + + Point_3 p1, p2, p3; + p1 = Point_3(1,0,0); + p2 = Point_3(0,1,0); + p3 = Point_3(0,0,1); + Circle_3 c = theConstruct_circle_3(p1, p2, p3); + FT r1 = squared_distance(c.center(), p1); + FT r2 = squared_distance(c.center(), p2); + FT r3 = squared_distance(c.center(), p3); + assert(r1 == r2); + assert(r2 == r3); + assert(r3 == c.squared_radius()); + + p1 = Point_3(1.3,0.2,0.1); + p2 = Point_3(0.57,1.23,3.0); + p3 = Point_3(9,1.2,1.3); + c = theConstruct_circle_3(p1, p2, p3); + r1 = squared_distance(c.center(), p1); + r2 = squared_distance(c.center(), p2); + r3 = squared_distance(c.center(), p3); + assert(r1 == r2); + assert(r2 == r3); + assert(r3 == c.squared_radius()); // No need to test the constructors based on intersection // _test_intersect_construct will test it