BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Nef_S2/Sphere_circle.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines