// ====================================================================== // // Copyright (c) 1999 The CGAL Consortium // // This software and related documentation is part of an INTERNAL release // of the Computational Geometry Algorithms Library (CGAL). It is not // intended for general use. // // ---------------------------------------------------------------------- // // release : // release_date : // // file : SphereH3.h // package : H3 // revision : $Revision$ // revision_date : $Date$ // author(s) : Stefan Schirra // // // coordinator : MPI, Saarbruecken () // ====================================================================== #ifndef CGAL_SPHEREH3_H #define CGAL_SPHEREH3_H #include #include #include #include CGAL_BEGIN_NAMESPACE template class Sphere_repH3 : public Ref_counted { public: typedef typename R::FT FT; friend class SphereH3; Sphere_repH3() {} Sphere_repH3(const PointH3 p, const FT sq_rad, const Orientation& o) : center(p), squared_radius(sq_rad), orientation_(o) {} protected: PointH3 center; FT squared_radius; Orientation orientation_; }; template class Simple_Sphere_repH3 { public: typedef typename R::FT FT; friend class SphereH3; Simple_Sphere_repH3() {} Simple_Sphere_repH3(const PointH3 p, const FT sq_rad, const Orientation& o) : center(p), squared_radius(sq_rad), orientation_(o) {} protected: PointH3 center; FT squared_radius; Orientation orientation_; }; template class SphereH3 : public R_::Sphere_handle_3 { public: typedef R_ R; typedef typename R::RT RT; typedef typename R::FT FT; typedef typename R::Sphere_handle_3 Sphere_handle_3_; typedef typename Sphere_handle_3_::element_type Sphere_ref_3; SphereH3() : Sphere_handle_3_() {} SphereH3(const PointH3& p, const FT& sq_rad, const Orientation& o = COUNTERCLOCKWISE); SphereH3(const PointH3& p, const PointH3& q, const PointH3& r, const PointH3& u); SphereH3(const PointH3& p, const PointH3& q, const PointH3& r, const Orientation& o = COUNTERCLOCKWISE); SphereH3(const PointH3& p, const PointH3& q, const Orientation& o = COUNTERCLOCKWISE); SphereH3(const PointH3& p, const Orientation& o = COUNTERCLOCKWISE); bool operator==(const SphereH3&) const; bool operator!=(const SphereH3& s) const { return !(*this == s); } const PointH3 & center() const; const FT & squared_radius() const; Orientation orientation() const; SphereH3 orthogonal_transform(const Aff_transformationH3& t) const; bool is_degenerate() const; SphereH3 opposite() const; Bbox_3 bbox() const; Oriented_side oriented_side(const PointH3& p) const; bool has_on_boundary(const PointH3& p) const { return oriented_side(p)==ON_ORIENTED_BOUNDARY; } bool has_on_positive_side(const PointH3& p) const { return oriented_side(p)==ON_POSITIVE_SIDE; } bool has_on_negative_side(const PointH3& p) const { return oriented_side(p)==ON_NEGATIVE_SIDE; } Bounded_side bounded_side(const PointH3& p) const; bool has_on_bounded_side(const PointH3& p) const { return bounded_side(p)==ON_BOUNDED_SIDE; } bool has_on_unbounded_side(const PointH3& p) const { return bounded_side(p)==ON_UNBOUNDED_SIDE; } }; template < class R > CGAL_KERNEL_CTOR_INLINE SphereH3::SphereH3(const PointH3& center, const FT& squared_radius, const Orientation& o) { CGAL_kernel_precondition( !( squared_radius < FT(0)) &&( o != COLLINEAR) ); initialize_with( Sphere_ref_3(center, squared_radius, o)); } template CGAL_KERNEL_CTOR_INLINE SphereH3::SphereH3(const PointH3& center, const Orientation& o) { CGAL_kernel_precondition( ( o != COLLINEAR) ); initialize_with( Sphere_ref_3(center, FT(0), o)); } template CGAL_KERNEL_CTOR_MEDIUM_INLINE SphereH3::SphereH3(const PointH3& p, const PointH3& q, const Orientation& o) { CGAL_kernel_precondition( o != COLLINEAR); PointH3 center = midpoint(p,q); FT squared_radius = squared_distance(p,center); initialize_with(Sphere_ref_3(center, squared_radius, o)); } template CGAL_KERNEL_CTOR_MEDIUM_INLINE SphereH3::SphereH3(const PointH3& p, const PointH3& q, const PointH3& r, const Orientation& o) { CGAL_kernel_precondition( o != COLLINEAR); PointH3 center = circumcenter(p,q,r); FT squared_radius = squared_distance(p,center); initialize_with(Sphere_ref_3(center, squared_radius, o)); } template CGAL_KERNEL_CTOR_MEDIUM_INLINE SphereH3::SphereH3(const PointH3& p, const PointH3& q, const PointH3& r, const PointH3& s) { Orientation o = CGAL::orientation(p,q,r,s); CGAL_kernel_precondition( o != COLLINEAR); PointH3 center = circumcenter(p,q,r,s); FT squared_radius = squared_distance(p,center); initialize_with(Sphere_ref_3(center, squared_radius, o)); } template CGAL_KERNEL_INLINE bool SphereH3::operator==(const SphereH3& s) const { return ( orientation() == s.orientation()) && ( center() == s.center()) && ( squared_radius() == s.squared_radius()); } template inline const PointH3 & SphereH3::center() const { return Ptr()->center; } template inline const typename SphereH3::FT & SphereH3::squared_radius() const { return Ptr()->squared_radius; } template inline Orientation SphereH3::orientation() const { return Ptr()->orientation_; } template inline bool SphereH3::is_degenerate() const { return Ptr()->squared_radius <= FT(0) ; } template CGAL_KERNEL_MEDIUM_INLINE Oriented_side SphereH3::oriented_side(const PointH3& p) const { return Oriented_side(bounded_side(p) * orientation()); } template CGAL_KERNEL_INLINE Bounded_side SphereH3::bounded_side(const PointH3& p) const { return Bounded_side(CGAL_NTS compare(squared_radius(), squared_distance(center(),p))); } template inline SphereH3 SphereH3::opposite() const { return SphereH3(center(), squared_radius(), CGAL::opposite(orientation()) ); } template CGAL_KERNEL_INLINE Bbox_3 SphereH3::bbox() const { double eps = double(1.0) /(double(1<<26) * double(1<<26)); double hxd = CGAL::to_double( center().hx() ); double hyd = CGAL::to_double( center().hy() ); double hzd = CGAL::to_double( center().hz() ); double hwd = CGAL::to_double( center().hw() ); double xmin = ( hxd - eps*hxd ) / ( hwd + eps*hwd ); double xmax = ( hxd + eps*hxd ) / ( hwd - eps*hwd ); double ymin = ( hyd - eps*hyd ) / ( hwd + eps*hwd ); double ymax = ( hyd + eps*hyd ) / ( hwd - eps*hwd ); double zmin = ( hzd - eps*hyd ) / ( hwd + eps*hwd ); double zmax = ( hzd + eps*hyd ) / ( hwd - eps*hwd ); if ( center().hx() < RT(0) ) { std::swap(xmin, xmax); } if ( center().hy() < RT(0) ) { std::swap(ymin, ymax); } if ( center().hz() < RT(0) ) { std::swap(zmin, zmax); } double sqradd = CGAL::to_double( squared_radius() ); sqradd += sqradd*eps; sqradd = sqrt(sqradd); sqradd += sqradd*eps; xmin -= sqradd; xmax += sqradd; xmin -= xmin*eps; xmax += xmax*eps; ymin -= sqradd; ymax += sqradd; ymin -= ymin*eps; ymax += ymax*eps; zmin -= sqradd; zmax += sqradd; zmin -= ymin*eps; zmax += ymax*eps; return Bbox_3(xmin, ymin, zmin, xmax, ymax, zmax); } CGAL_END_NAMESPACE #endif // CGAL_SPHEREH3_H