BWAPI
|
00001 // Copyright (c) 2008 INRIA Sophia-Antipolis (France). 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/Circular_kernel_3/include/CGAL/Circular_kernel_3/Line_arc_3.h $ 00015 // $Id: Line_arc_3.h 50731 2009-07-21 09:08:07Z sloriot $ 00016 // 00017 // Author(s) : Monique Teillaud, Sylvain Pion, Pedro Machado, 00018 // Sebastien Loriot, Julien Hazebrouck, Damien Leroy 00019 00020 // Partially supported by the IST Programme of the EU as a 00021 // STREP (FET Open) Project under Contract No IST-006413 00022 // (ACS -- Algorithms for Complex Shapes) 00023 00024 #ifndef CGAL_SPHERICAL_KERNEL_LINE_ARC_3_H 00025 #define CGAL_SPHERICAL_KERNEL_LINE_ARC_3_H 00026 00027 #include <CGAL/Circular_kernel_3/internal_functions_on_sphere_3.h> 00028 #include <boost/tuple/tuple.hpp> 00029 00030 namespace CGAL { 00031 namespace CGALi{ 00032 template <class SK> class Line_arc_3 { 00033 00034 typedef typename SK::Plane_3 Plane_3; 00035 typedef typename SK::Sphere_3 Sphere_3; 00036 typedef typename SK::Point_3 Point_3; 00037 typedef typename SK::Segment_3 Segment_3; 00038 typedef typename SK::Circular_arc_point_3 Circular_arc_point_3; 00039 typedef typename SK::Line_3 Line_3; 00040 typedef typename SK::FT FT; 00041 00042 private: 00043 typedef boost::tuple<Line_3, Circular_arc_point_3, 00044 Circular_arc_point_3> Rep; 00045 typedef typename SK::template Handle<Rep>::type Base; 00046 00047 Base base; 00048 mutable unsigned char begin_less_xyz_than_end_flag; 00049 00050 bool begin_less_xyz_than_end() const { 00051 if(begin_less_xyz_than_end_flag == 0) { 00052 if(SK().compare_xyz_3_object()(source(), target()) < 0) 00053 begin_less_xyz_than_end_flag = 2; 00054 else begin_less_xyz_than_end_flag = 1; 00055 } return begin_less_xyz_than_end_flag == 2; 00056 } 00057 00058 public: 00059 Line_arc_3() 00060 : begin_less_xyz_than_end_flag(0) 00061 {} 00062 00063 Line_arc_3(const Line_3 &l, 00064 const Circular_arc_point_3 &s, 00065 const Circular_arc_point_3 &t) 00066 : begin_less_xyz_than_end_flag(0) 00067 { 00068 // l must pass through s and t, and s != t 00069 CGAL_kernel_precondition(SK().has_on_3_object()(l,s)); 00070 CGAL_kernel_precondition(SK().has_on_3_object()(l,t)); 00071 CGAL_kernel_precondition(s != t); 00072 base = Rep(l,s,t); 00073 } 00074 00075 Line_arc_3(const Segment_3 &s) 00076 : begin_less_xyz_than_end_flag(0) 00077 { 00078 base = Rep(s.supporting_line(), 00079 s.source(), 00080 s.target()); 00081 } 00082 00083 Line_arc_3(const Point_3 &s, 00084 const Point_3 &t) 00085 : begin_less_xyz_than_end_flag(0) 00086 { 00087 CGAL_kernel_precondition(s != t); 00088 base = Rep(SK().construct_line_3_object()(s,t),s,t); 00089 } 00090 00091 Line_arc_3(const Line_3 &l, 00092 const Sphere_3 &s, 00093 bool less_xyz_first = true) 00094 { 00095 std::vector<Object> sols; 00096 SK().intersect_3_object()(l, s, std::back_inserter(sols)); 00097 // l must intersect s in 2 points 00098 CGAL_kernel_precondition(sols.size() == 2); 00099 const std::pair<typename SK::Circular_arc_point_3, unsigned>& pair1= 00100 *object_cast<std::pair<typename SK::Circular_arc_point_3, unsigned> >(&sols[0]); 00101 const std::pair<typename SK::Circular_arc_point_3, unsigned>& pair2= 00102 *object_cast<std::pair<typename SK::Circular_arc_point_3, unsigned> >(&sols[1]); 00103 if(less_xyz_first) { 00104 *this = Line_arc_3(l, pair1.first, pair2.first); 00105 } else { 00106 *this = Line_arc_3(l, pair2.first, pair1.first); 00107 } 00108 } 00109 00110 Line_arc_3(const Line_3 &l, 00111 const Sphere_3 &s1, bool less_xyz_s1, 00112 const Sphere_3 &s2, bool less_xyz_s2) 00113 { 00114 std::vector<Object> sols1, sols2; 00115 SK().intersect_3_object()(l, s1, std::back_inserter(sols1)); 00116 SK().intersect_3_object()(l, s2, std::back_inserter(sols2)); 00117 // l must intersect s1 and s2 00118 CGAL_kernel_precondition(sols1.size() > 0); 00119 CGAL_kernel_precondition(sols2.size() > 0); 00120 const std::pair<typename SK::Circular_arc_point_3, unsigned>& pair1= 00121 *object_cast<std::pair<typename SK::Circular_arc_point_3, unsigned> >(&sols1[(sols1.size()==1)?(0):(less_xyz_s1?0:1)]); 00122 const std::pair<typename SK::Circular_arc_point_3, unsigned>& pair2= 00123 *object_cast<std::pair<typename SK::Circular_arc_point_3, unsigned> >(&sols2[(sols2.size()==1)?(0):(less_xyz_s2?0:1)]); 00124 // the source and target must be different 00125 CGAL_kernel_precondition(pair1.first != pair2.first); 00126 *this = Line_arc_3(l, pair1.first, pair2.first); 00127 } 00128 00129 Line_arc_3(const Line_3 &l, 00130 const Plane_3 &p1, 00131 const Plane_3 &p2) 00132 { 00133 // l must not be on p1 or p2 00134 CGAL_kernel_precondition(!SK().has_on_3_object()(p1,l)); 00135 CGAL_kernel_precondition(!SK().has_on_3_object()(p2,l)); 00136 // l must intersect p1 and p2 00137 const typename SK::Point_3* point1=object_cast<typename SK::Point_3>( & SK().intersect_3_object()(l, p1) ); 00138 const typename SK::Point_3* point2=object_cast<typename SK::Point_3>( & SK().intersect_3_object()(l, p2) ); 00139 CGAL_assertion(point1!=NULL); 00140 CGAL_assertion(point2!=NULL); 00141 // the source and target must be different 00142 CGAL_kernel_precondition(*point1 != *point2); 00143 *this = Line_arc_3(l, *point1, *point2); 00144 } 00145 00146 const Line_3& supporting_line() const 00147 { 00148 return get(base).get<0>(); 00149 } 00150 00151 const Circular_arc_point_3& source() const 00152 { 00153 return get(base).get<1>(); 00154 } 00155 00156 const Circular_arc_point_3& target() const 00157 { 00158 return get(base).get<2>(); 00159 } 00160 00161 const Circular_arc_point_3& lower_xyz_extremity() const 00162 { 00163 return begin_less_xyz_than_end() ? source() : target(); 00164 } 00165 00166 const Circular_arc_point_3& higher_xyz_extremity() const 00167 { 00168 return begin_less_xyz_than_end() ? target() : source(); 00169 } 00170 00171 const CGAL::Bbox_3 bbox() const { 00172 return source().bbox() + target().bbox(); 00173 } 00174 00175 bool operator==(const Line_arc_3 &) const; 00176 bool operator!=(const Line_arc_3 &) const; 00177 00178 }; 00179 00180 template < class SK > 00181 CGAL_KERNEL_INLINE 00182 bool 00183 Line_arc_3<SK>::operator==(const Line_arc_3<SK> &t) const 00184 { 00185 if (CGAL::identical(base, t.base)) 00186 return true; 00187 return CGAL::SphericalFunctors::non_oriented_equal<SK>(*this, t); 00188 } 00189 00190 template < class SK > 00191 CGAL_KERNEL_INLINE 00192 bool 00193 Line_arc_3<SK>::operator!=(const Line_arc_3<SK> &t) const 00194 { 00195 return !(*this == t); 00196 } 00197 00198 } 00199 } 00200 00201 #endif