BWAPI
|
00001 // Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry.h $ 00015 // $Id: Sphere_geometry.h 35146 2006-11-13 13:43:37Z hachenb $ 00016 // 00017 // 00018 // Author(s) : Michael Seel <seel@mpi-inf.mpg.de> 00019 // Peter Hachenberger <hachenberger@mpi-inf.mpg.de> 00020 00021 #ifndef CGAL_SPHERE_GEOMETRY_H 00022 #define CGAL_SPHERE_GEOMETRY_H 00023 00024 #include <CGAL/basic.h> 00025 #include <CGAL/intersection_3.h> 00026 #include <list> 00027 00028 #undef CGAL_NEF_DEBUG 00029 #define CGAL_NEF_DEBUG 113 00030 #include <CGAL/Nef_2/debug.h> 00031 00032 CGAL_BEGIN_NAMESPACE 00033 00034 template <class R> class Sphere_point; 00035 template <class R> class Sphere_segment; 00036 template <class R> class Sphere_triangle; 00037 template <class R> class Sphere_circle; 00038 template <class R> class Sphere_direction; 00039 00040 CGAL_END_NAMESPACE 00041 00042 #include <CGAL/Nef_S2/Sphere_point.h> 00043 #include <CGAL/Nef_S2/Sphere_circle.h> 00044 #include <CGAL/Nef_S2/Sphere_direction.h> 00045 #include <CGAL/Nef_S2/Sphere_segment.h> 00046 #include <CGAL/Nef_S2/Sphere_triangle.h> 00047 #include <CGAL/Nef_S2/sphere_predicates.h> 00048 00049 CGAL_BEGIN_NAMESPACE 00050 00051 template <typename R_> 00052 struct Positive_halfsphere_geometry { 00053 00054 typedef R_ R; 00055 typedef CGAL::Sphere_point<R> Point_2; 00056 typedef CGAL::Sphere_segment<R> Segment_2; 00057 00058 int axis; 00059 00060 Positive_halfsphere_geometry() : axis(2) {} 00061 Positive_halfsphere_geometry(int check_sphere) : axis(check_sphere) {} 00062 00063 Point_2 source(const Segment_2& s) const 00064 { return s.source(); } 00065 Point_2 target(const Segment_2& s) const 00066 { return s.target(); } 00067 Segment_2 construct_segment(const Point_2& p, const Point_2& q) const 00068 { return Segment_2(p,q); } 00069 00070 void xz_pi_half_rotate(Point_2& p) const 00071 { p = Point_2(-p.hz(),p.hy(),p.hx()); } 00072 00073 void zx_pi_half_rotate(Point_2& p) const 00074 { p = Point_2(-p.hz(),p.hy(),p.hx()); } 00075 00076 void xy_pi_half_rotate(Point_2& p) const 00077 { p = Point_2(-p.hy(),p.hx(),p.hz()); } 00078 00079 int orientation(const Point_2& p1, const Point_2& p2, 00080 const Point_2& p3) const { 00081 00082 int sor = CGAL::spherical_orientation(p1,p2,p3); 00083 if (sor) return sor; 00084 Point_2 pp1(p1), pp2(p2), pp3(p3); 00085 switch(axis) { 00086 case 0: 00087 if ( !( p1.hx() == 0 && p2.hx() == 0 && p3.hx() == 0) ) return sor; 00088 if ( p1.hz()<0 ) zx_pi_half_rotate(pp1); 00089 if ( p2.hz()<0 ) zx_pi_half_rotate(pp2); 00090 if ( p3.hz()<0 ) zx_pi_half_rotate(pp3); 00091 return CGAL::spherical_orientation(pp1,pp2,pp3); 00092 break; 00093 case 1: 00094 if ( !( p1.hy() == 0 && p2.hy() == 0 && p3.hy() == 0) ) return sor; 00095 if ( p1.hx()>0 ) xy_pi_half_rotate(pp1); 00096 if ( p2.hx()>0 ) xy_pi_half_rotate(pp2); 00097 if ( p3.hx()>0 ) xy_pi_half_rotate(pp3); 00098 return CGAL::spherical_orientation(pp1,pp2,pp3); 00099 break; 00100 case 2: 00101 if ( !( p1.hz() == 0 && p2.hz() == 0 && p3.hz() == 0) ) return sor; 00102 // sor==0 we perturb any point in the xy-plane with x>0 00103 // by a negative rotation around the y-axis 00104 // our perturbation is big :-) we take PI/2 : 00105 if ( p1.hx()>0 ) xz_pi_half_rotate(pp1); 00106 if ( p2.hx()>0 ) xz_pi_half_rotate(pp2); 00107 if ( p3.hx()>0 ) xz_pi_half_rotate(pp3); 00108 return CGAL::spherical_orientation(pp1,pp2,pp3); 00109 break; 00110 } 00111 return 0; 00112 } 00113 00114 int orientation(const Segment_2& s, const Point_2& p) const 00115 { return orientation(s.source(),s.target(),p); } 00116 00117 bool is_degenerate(const Segment_2& s) const 00118 { return s.is_degenerate(); } 00119 00120 int compare_xy(const Point_2& p1, const Point_2& p2) const { 00121 CGAL_NEF_TRACEN("compare_xy " << axis << ":" << p1 << " / " << p2); 00122 return CGAL::spherical_compare(p1,p2,axis,+1); 00123 } 00124 00125 Point_2 intersection(const Segment_2& s1, const Segment_2& s2) const 00126 { if (s1.sphere_circle() != s2.sphere_circle().opposite()) 00127 return s1.intersection(s2); 00128 CGAL_assertion(s1.target()==s2.target()); 00129 return s1.target(); 00130 } 00131 00132 }; // Positive_halfsphere_geometry<R> 00133 00134 template <typename R> 00135 struct Negative_halfsphere_geometry : 00136 public Positive_halfsphere_geometry<R> { 00137 00138 typedef Positive_halfsphere_geometry<R> Base; 00139 typedef typename Base::Point_2 Point_2; 00140 typedef typename Base::Segment_2 Segment_2; 00141 00142 Negative_halfsphere_geometry() : Base() {} 00143 Negative_halfsphere_geometry(int check_sphere) : Base(check_sphere) {} 00144 00145 int orientation(const Point_2& p1, const Point_2& p2, 00146 const Point_2& p3) const { 00147 00148 int sor = CGAL::spherical_orientation(p1,p2,p3); 00149 if (sor) return sor; 00150 Point_2 pp1(p1), pp2(p2), pp3(p3); 00151 switch(((Base*) this)->axis) { 00152 case 0: 00153 if ( !( p1.hx() == 0 && p2.hx() == 0 && p3.hx() == 0) ) return sor; 00154 if ( p1.hz()>0 ) zx_pi_half_rotate(pp1); 00155 if ( p2.hz()>0 ) zx_pi_half_rotate(pp2); 00156 if ( p3.hz()>0 ) zx_pi_half_rotate(pp3); 00157 return CGAL::spherical_orientation(pp1,pp2,pp3); 00158 break; 00159 case 1: 00160 if ( !( p1.hy() == 0 && p2.hy() == 0 && p3.hy() == 0) ) return sor; 00161 if ( p1.hx()<0 ) xy_pi_half_rotate(pp1); 00162 if ( p2.hx()<0 ) xy_pi_half_rotate(pp2); 00163 if ( p3.hx()<0 ) xy_pi_half_rotate(pp3); 00164 return CGAL::spherical_orientation(pp1,pp2,pp3); 00165 break; 00166 case 2: 00167 if ( !( p1.hz() == 0 && p2.hz() == 0 && p3.hz() == 0) ) return sor; 00168 // sor==0 we perturb any point in the xy-plane with x>0 00169 // by a negative rotation around the y-axis 00170 // our perturbation is big :-) we take PI/2 : 00171 if ( p1.hx()<0 ) xz_pi_half_rotate(pp1); 00172 if ( p2.hx()<0 ) xz_pi_half_rotate(pp2); 00173 if ( p3.hx()<0 ) xz_pi_half_rotate(pp3); 00174 return CGAL::spherical_orientation(pp1,pp2,pp3); 00175 break; 00176 } 00177 return 0; 00178 } 00179 00180 int orientation(const Segment_2& s, const Point_2& p) const 00181 { return orientation(s.source(),s.target(),p); } 00182 00183 int compare_xy(const Point_2& p1, const Point_2& p2) const 00184 { return CGAL::spherical_compare(p1,p2,this->axis,-1); } 00185 00186 }; // Negative_halfsphere_geometry<R> 00187 00188 template <typename R_> 00189 struct Sphere_geometry { 00190 00191 typedef R_ R; 00192 typedef typename R_::RT RT; 00193 typedef typename R_::FT FT; 00194 typedef CGAL::Sphere_point<R> Sphere_point; 00195 typedef CGAL::Sphere_segment<R> Sphere_segment; 00196 typedef CGAL::Sphere_circle<R> Sphere_circle; 00197 typedef CGAL::Sphere_direction<R> Sphere_direction; 00198 typedef CGAL::Sphere_triangle<R> Sphere_triangle; 00199 typedef typename R::Point_3 Point_3; 00200 typedef typename R::Plane_3 Plane_3; 00201 typedef typename R::Aff_transformation_3 Aff_transformation_3; 00202 typedef CGAL::Positive_halfsphere_geometry<R> Positive_halfsphere_geometry; 00203 typedef CGAL::Negative_halfsphere_geometry<R> Negative_halfsphere_geometry; 00204 00205 Sphere_point source(const Sphere_segment& s) const 00206 { return s.source(); } 00207 00208 Sphere_point target(const Sphere_segment& s) const 00209 { return s.target(); } 00210 00211 Sphere_segment construct_segment(const Sphere_point& p, 00212 const Sphere_point& q) const 00213 { return Sphere_segment(p,q); } 00214 00215 Sphere_segment construct_segment(const Sphere_point& p, 00216 const Sphere_point& q, 00217 const Plane_3& h) const 00218 { return Sphere_segment(p,q,Sphere_circle(h)); } 00219 00220 Plane_3 affine_representation(const Plane_3& h, const Point_3& p) const 00221 { RT wp = p.hw(); 00222 return Plane_3(wp*h.a(),wp*h.b(),wp*h.c(), 00223 -(p.hx()*h.a() + p.hy()*h.b() + p.hz()*h.c())); } 00224 00225 Plane_3 linear_representation(const Plane_3& h) const 00226 { return Plane_3(h.a(),h.b(),h.c(),0); } 00227 00228 /* 00229 Positive_halfsphere_geometry PHG; 00230 const Positive_halfsphere_geometry& 00231 get_positive_halfsphere_geometry() const 00232 { return PHG; } 00233 00234 Negative_halfsphere_geometry NHG; 00235 const Negative_halfsphere_geometry& 00236 get_negative_halfsphere_geometry() const 00237 { return NHG; } 00238 */ 00239 00240 const Positive_halfsphere_geometry& 00241 get_positive_halfsphere_geometry(int a) const { 00242 return Positive_halfsphere_geometry(a); 00243 } 00244 00245 const Negative_halfsphere_geometry& 00246 get_negative_halfsphere_geometry(int a) const { 00247 return Negative_halfsphere_geometry(a); 00248 } 00249 00250 }; 00251 00252 00253 00254 CGAL_END_NAMESPACE 00255 #endif //CGAL_SPHERE_GEOMETRY_H 00256