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_circle.h $ 00015 // $Id: Sphere_circle.h 44480 2008-07-26 20:26:48Z hachenb $ 00016 // 00017 // 00018 // Author(s) : Michael Seel <seel@mpi-sb.mpg.de> 00019 00020 #ifndef CGAL_SPHERE_CIRCLE_H 00021 #define CGAL_SPHERE_CIRCLE_H 00022 00023 #include <CGAL/basic.h> 00024 00025 CGAL_BEGIN_NAMESPACE 00026 00027 template <class R> class Sphere_segment; 00028 00029 /*{\Manpage{Sphere_circle}{R}{Great circles on the unit sphere}{c}}*/ 00030 00031 template <class R_> class Sphere_circle : public R_::Plane_3 { 00032 00033 /*{\Mdefinition An object |\Mvar| of type |\Mname| is an oriented 00034 great circle on the surface of a unit sphere. Such circles correspond 00035 to the intersection of an oriented plane (that contains the origin) 00036 and the surface of $S_2$. The orientation of the great circle is that 00037 of a counterclockwise walk along the circle as seen from the positive 00038 halfspace of the oriented plane.}*/ 00039 00040 public: 00041 00042 /*{\Mtypes 5}*/ 00043 typedef R_ R; 00044 /*{\Mtypemember representation class.}*/ 00045 typedef typename R::RT RT; 00046 /*{\Mtypemember ring type.}*/ 00047 typedef std::pair< Sphere_segment<R>,Sphere_segment<R> > 00048 Sphere_segment_pair; 00049 /*{\Mtypemember sphere segment pair.}*/ 00050 00051 typedef typename R_::Plane_3 Plane_3; 00052 typedef typename R_::Line_3 Line_3; 00053 typedef typename R_::Point_3 Point_3; 00054 typedef Sphere_circle<R_> Self; 00055 typedef typename R_::Plane_3 Base; 00056 00057 /*{\Mcreation 5}*/ 00058 Sphere_circle() : Base() {} 00059 /*{\Mcreate creates some great circle.}*/ 00060 00061 Sphere_circle(const Sphere_point<R>& p, const Sphere_point<R>&q) 00062 : Base(Point_3(0,0,0),p,q) 00063 /*{\Mcreate creates a great circle through $p$ and $q$. If $p$ and 00064 $q$ are not antipodal on $S_2$, then this circle is unique and oriented 00065 such that a walk along |\Mvar| meets $p$ just before the shorter segment 00066 between $p$ and $q$. If $p$ and $q$ are antipodal of each other then we 00067 create any great circle that contains $p$ and $q$.}*/ 00068 { Point_3 p1(0,0,0), p4 = CGAL::ORIGIN + ((Base*) this)->orthogonal_vector(); 00069 if ( p != q.antipode() ) { 00070 if (R_().orientation_3_object()(p1,p,q,p4) != CGAL::POSITIVE ) 00071 *this = Self(opposite()); 00072 } else { 00073 /* previous method was: *this = Self(Plane_3(p1,q-p)); 00074 but p, q don't belong to he plane ((0,0,0), q-p) */ 00075 00076 if(!Line_3(p,q).has_on(Point_3(1,0,0))) 00077 *this = Self(Plane_3(p,q,Point_3(1,0,0))); 00078 else 00079 *this = Self(Plane_3(p,q,Point_3(0,1,0))); 00080 /* take one point that doesn't belong to the line (p, q-p) */ 00081 } 00082 } 00083 00084 Sphere_circle(const Plane_3& h) : Base(h) 00085 /*{\Mcreate creates the circle of $S_2$ corresponding to the plane 00086 |h|. If |h| does not contain the origin, then |\Mvar| becomes the 00087 circle parallel to |h| containing the origin.}*/ 00088 { 00089 if(h.d() != 0) *this = Plane_3(h.a(),h.b(),h.c(),RT(0)); 00090 } 00091 00092 Sphere_circle(const RT& x, const RT& y, const RT& z): Base(x,y,z,0) {} 00093 00094 /*{\Mcreate creates the circle orthogonal to the vector $(x,y,z)$.}*/ 00095 00096 Sphere_circle(Sphere_circle<R> c, const Sphere_point<R>& p) 00097 /*{\Mcreate creates a great circle orthogonal to $c$ that contains $p$. 00098 \precond $p$ is not part of $c$.}*/ 00099 { CGAL_assertion(!c.has_on(p)); 00100 if ( c.has_on_negative_side(p) ) c=c.opposite(); 00101 if ( p == c.orthogonal_pole() ) 00102 *this = Sphere_circle<R>(Base(Point_3(0,0,0),p,CGAL::ORIGIN+c.base1())); 00103 else 00104 *this = Sphere_circle<R>(Base(Point_3(0,0,0),p,c.orthogonal_pole())); 00105 } 00106 00107 /*{\Moperations 4 2}*/ 00108 00109 Sphere_circle<R> opposite() const 00110 /*{\Mop returns the opposite of |\Mvar|.}*/ 00111 { return Base::opposite(); } 00112 00113 bool has_on(const Sphere_point<R>& p) const 00114 /*{\Mop returns true iff |\Mvar| contains |p|.}*/ 00115 { return Base::has_on(p); } 00116 00117 Plane_3 plane() const { return Base(*this); } 00118 /*{\Mop returns the plane supporting |\Mvar|.}*/ 00119 00120 Plane_3 plane_through(const Point_3& p) const 00121 /*{\Mop returns the plane parallel to |\Mvar| that 00122 contains point |p|.}*/ 00123 { return Plane_3(p,((Base*) this)->orthogonal_direction()); } 00124 00125 Sphere_point<R> orthogonal_pole() const 00126 /*{\Mop returns the point that is the pole of the 00127 hemisphere left of |\Mvar|.}*/ 00128 { return CGAL::ORIGIN+((Base*) this)->orthogonal_vector(); } 00129 00130 Sphere_segment_pair split_at(const Sphere_point<R>& p) const; 00131 /*{\Mop returns the pair of circle segments that is the result 00132 of splitting |\Mvar| at |p| and |p.antipode()|.}*/ 00133 00134 Sphere_segment_pair split_at_xy_plane() const; 00135 /*{\Mop returns the pair of circle segments that is the result 00136 of splitting |\Mvar| at the $x$-$y$-coordinate plane if |\Mvar| 00137 is not part of it. Otherwise |\Mvar| is split at the 00138 $x$-$z$-coordinate plane.}*/ 00139 00140 }; // Sphere_circle<R> 00141 00142 /*{\Mtext\headerline{Global functions}}*/ 00143 00144 template <class R> 00145 bool equal_as_sets(const CGAL::Sphere_circle<R>& c1, 00146 const CGAL::Sphere_circle<R>& c2) 00147 /*{\Mfunc returns true iff |c1| and |c2| are equal as unoriented 00148 circles.}*/ 00149 { return c1==c2 || c1==c2.opposite(); } 00150 00151 template <class R> 00152 bool equal_not_opposite(const CGAL::Sphere_circle<R>& c1, 00153 const CGAL::Sphere_circle<R>& c2) { 00154 // function should be called to decide whether two circles 00155 // are equal or opposites. returns true iff |c1| and |c2| are equal 00156 if(c1.a() != 0) return sign(c1.a()) == sign(c2.a()); 00157 if(c1.b() != 0) return sign(c1.b()) == sign(c2.b()); 00158 return sign(c1.c()) == sign(c2.c()); 00159 } 00160 00161 template <typename R> 00162 Sphere_point<R> intersection(const Sphere_circle<R>& c1, 00163 const Sphere_circle<R>& c2) 00164 /*{\Mfunc returns one of the two intersection points of 00165 |c1| and |c2|. \precond |c1 != c2| as sets.}*/ 00166 { 00167 CGAL_assertion(!equal_as_sets(c1,c2)); 00168 typename R::Line_3 lres; 00169 CGAL_NEF_TRACEN("circle_intersection "<<c1<<" "<<c2); 00170 CGAL::Object o = CGAL::intersection(c1.plane(),c2.plane()); 00171 if ( !CGAL::assign(lres,o) ) CGAL_error(); 00172 return CGAL::ORIGIN + lres.direction().vector(); 00173 } 00174 00175 00176 CGAL_END_NAMESPACE 00177 #endif //CGAL_SPHERE_CIRCLE_H