Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

geom_tools.h

Go to the documentation of this file.
00001 
00051 #ifndef __GEOM_TOOLS__
00052 #define __GEOM_TOOLS__
00053 
00054 #include <cmath>
00055 
00056 #include "geom.h"
00057 
00058 namespace Geom_tools{
00059 
00060   using namespace Geometry;
00061   
00062   template<typename Real>
00063   Real min_distance_2_lines(const Vec3<Real>& base1,
00064                             const Vec3<Real>& direction1,
00065                             const Vec3<Real>& base2,
00066                             const Vec3<Real>& direction2,
00067                             Vec3<Real>* const cross_point = NULL);
00068 
00069   
00070   
00071 
00072   template<typename Real>
00073   inline void plane_equation(const Vec3<Real>& base,
00074                              const Vec3<Real>& normal,
00075                              Hvec3<Real>* const plane);
00076 
00077 
00078   template<typename Real>
00079   inline void plane_equation(const Vec3<Real>& base,
00080                              const Vec3<Real>& dir1,
00081                              const Vec3<Real>& dir2,
00082                              Hvec3<Real>* const plane);
00083 
00084 
00085   template<typename Real>
00086   inline bool on_same_side_of_plane(const Hvec3<Real>& plane,
00087                                     const Vec3<Real>& p1,
00088                                     const Vec3<Real>& p2);
00089 
00090   
00091   template<typename Real>
00092   void plane_line_intersection(const Vec3<Real>& base,
00093                                const Vec3<Real>& direction,
00094                                const Hvec3<Real>& plane,
00095                                Vec3<Real>* const cross);
00096   
00097 
00098   
00099   template<typename Real>
00100   bool nearest_sphere_line_intersection(const Vec3<Real>& base,
00101                                         const Vec3<Real>& direction,
00102                                         const Vec3<Real>& center,
00103                                         const Real        radius,
00104                                         Vec3<Real>* const cross);
00105 
00106   
00107 
00108    template<typename Real>
00109   bool oriented_sphere_line_intersection(const Vec3<Real>& base,
00110                                          const Vec3<Real>& direction,
00111                                          const Vec3<Real>& center,
00112                                          const Real        radius,
00113                                          Vec3<Real>* const cross);
00114 
00115 
00116   
00117   template<typename Real> bool
00118   oriented_ellipsoid_line_intersection(const Vec3<Real>&            base,
00119                                        const Vec3<Real>&            direction,
00120                                        const Vec3<Real>&            center,
00121                                        const Square_matrix<3,Real>& matrix,
00122                                        Vec3<Real>* const            cross);
00123 
00124 
00125   
00126   template<typename Real>
00127   void define_centered_ellipsoid(const Vec3<Real>&            x_axis,
00128                                  const Vec3<Real>&            y_axis,
00129                                  const Vec3<Real>&            z_axis,
00130                                  const Real                   x_radius,
00131                                  const Real                   y_radius,
00132                                  const Real                   z_radius,
00133                                  Square_matrix<3,Real>* const result);
00134 
00135   
00136   template<typename Real>
00137   bool point_inside_ellipsoid(const Vec3<Real>&            point,
00138                               const Vec3<Real>&            center,
00139                               const Square_matrix<3,Real>& matrix);
00140   
00141 
00142 
00143   
00144 /*
00145   
00146   #############################################
00147   #############################################
00148   #############################################
00149   ######                                 ######
00150   ######   I M P L E M E N T A T I O N   ######
00151   ######                                 ######
00152   #############################################
00153   #############################################
00154   #############################################
00155   
00156 */
00157 
00158 
00159 
00160 
00161 
00162 
00163   
00164   template<typename Real>
00165   Real min_distance_2_lines(const Vec3<Real>& base1,
00166                             const Vec3<Real>& direction1,
00167                             const Vec3<Real>& base2,
00168                             const Vec3<Real>& direction2,
00169                             Vec3<Real>* const cross_point){
00170 
00171     typedef Real             real_type;
00172     typedef Vec3<real_type>  vector_type;
00173     typedef Vec3<real_type>  point_type;
00174     typedef Hvec3<real_type> plane_type;
00175     
00176     const vector_type normal = (direction1^direction2).normalize();
00177     const real_type dist = std::abs((base1-base2)*normal);
00178                                      
00179     if (cross_point == NULL){
00180       return dist;
00181     }
00182 
00183 
00184     // Compute nearest point to line1 on line2.
00185     
00186     plane_type plane1;
00187     const vector_type normal1 = (direction1^normal).normalize();
00188     plane_equation(base1,normal1,&plane1);
00189     
00190     point_type cross1;
00191     plane_line_intersection(base2,direction2,plane1,&cross1);
00192 
00193 
00194     // Compute nearest point to line2 on line1.
00195 
00196     plane_type plane2;
00197     const vector_type normal2 = (direction2^normal).normalize();
00198     plane_equation(base2,normal2,&plane2);
00199     
00200     point_type cross2;
00201     plane_line_intersection(base1,direction1,plane2,&cross2);
00202 
00203 
00204     // Return center point.
00205     
00206     *cross_point = 0.5 * (cross1 + cross2);
00207 
00208     return dist;
00209   }
00210 
00211 
00212 
00213 
00214 
00215   
00216   template<typename Real>
00217   void plane_equation(const Vec3<Real>& base,
00218                       const Vec3<Real>& normal,
00219                       Hvec3<Real>* const plane){
00220 
00221     *plane = Hvec3<Real>(normal,-base*normal);
00222   }
00223 
00224   
00225   template<typename Real>
00226   void plane_equation(const Vec3<Real>& base,
00227                       const Vec3<Real>& dir1,
00228                       const Vec3<Real>& dir2,
00229                       Hvec3<Real>* const plane){
00230 
00231     plane_equation(base,dir1^dir2,plane);
00232   }
00233 
00234 
00235   /* Epsilon to robustify the choice */
00236   template<typename Real>
00237   inline bool on_same_side_of_plane(const Hvec3<Real>& plane,
00238                                     const Vec3<Real>& p1,
00239                                     const Vec3<Real>& p2){
00240     
00241     return ((plane*Hvec3<Real>(p1,1)) * (plane*Hvec3<Real>(p2,1)) >= 0);
00242   }
00243 
00244   
00245   template<typename Real>
00246   void plane_line_intersection(const Vec3<Real>&  base,
00247                                const Vec3<Real>&  direction,
00248                                const Hvec3<Real>& plane,
00249                                Vec3<Real>* const  cross){
00250 
00251     typedef Real real_type;
00252 
00253     const Hvec3<Real> base_proxy(base,1);
00254     const Hvec3<Real> direction_proxy(direction,0);
00255 
00256     const real_type base_value = base_proxy*plane;
00257     const real_type direction_value = direction_proxy*plane;
00258 
00259     *cross = base - direction * (base_value / direction_value);
00260   }
00261 
00262 
00263 
00264 
00265   template<typename Real>
00266   bool nearest_sphere_line_intersection(const Vec3<Real>& base,
00267                                         const Vec3<Real>& direction,
00268                                         const Vec3<Real>& center,
00269                                         const Real        radius,
00270                                         Vec3<Real>* const cross){
00271 
00272     typedef Real            real_type;
00273     typedef Vec3<real_type> vector_type;
00274     typedef Vec3<real_type> point_type;
00275 
00276     const vector_type center2base = base - center;
00277 
00278     const real_type c2b_d = center2base * direction;
00279     const real_type sq_d = direction.square_norm();
00280 
00281     const real_type delta =
00282       c2b_d*c2b_d - sq_d*(center2base.square_norm() - radius*radius);
00283 
00284     // No intersection
00285     if (delta<0){
00286       return false;
00287     }
00288 
00289     const real_type t = (-c2b_d + ((c2b_d<0)?-1:1) * std::sqrt(delta)) / sq_d;
00290 
00291     *cross = base + t*direction;
00292     return true;
00293   }
00294 
00295 
00296 
00297   template<typename Real>
00298   bool oriented_sphere_line_intersection(const Vec3<Real>& base,
00299                                          const Vec3<Real>& direction,
00300                                          const Vec3<Real>& center,
00301                                          const Real        radius,
00302                                          Vec3<Real>* const cross){
00303 
00304     typedef Real            real_type;
00305     typedef Vec3<real_type> vector_type;
00306     typedef Vec3<real_type> point_type;
00307 
00308     const vector_type center2base = base - center;
00309 
00310     const real_type c2b_d = center2base * direction;
00311     const real_type sq_d = direction.square_norm();
00312 
00313     const real_type delta =
00314       c2b_d*c2b_d - sq_d*(center2base.square_norm() - radius*radius);
00315 
00316     // No intersection
00317     if (delta<0){
00318       return false;
00319     }
00320 
00321     const real_type sqrt_delta = std::sqrt(delta);
00322     
00323     const real_type t_minus = (-c2b_d - sqrt_delta) / sq_d;
00324     const real_type t_plus  = (-c2b_d + sqrt_delta) / sq_d;
00325 
00326     const real_type t = (t_minus*t_plus<0) ? t_plus : t_minus;
00327 
00328     *cross = base + t*direction;
00329     return true;
00330   }
00331 
00332 
00333   template<typename Real> bool
00334   oriented_ellipsoid_line_intersection(const Vec3<Real>&            base,
00335                                        const Vec3<Real>&            direction,
00336                                        const Vec3<Real>&            center,
00337                                        const Square_matrix<3,Real>& matrix,
00338                                        Vec3<Real>* const            cross){
00339 
00340     typedef Real            real_type;
00341     typedef Vec3<real_type> vector_type;
00342     typedef Vec3<real_type> point_type;
00343 
00344     const vector_type center2base = base - center;
00345     const vector_type matrix_dir  = matrix * direction;
00346     const vector_type matrix_c2b  = matrix * center2base;
00347 
00348     const real_type a = direction * matrix_dir;
00349     const real_type b = direction * matrix_c2b;
00350     const real_type c = center2base * matrix_c2b - static_cast<real_type>(1);
00351 
00352     const real_type delta = b*b - a*c;
00353 
00354     if (delta<0){
00355       return false;
00356     }
00357     else{
00358       
00359       const real_type sqrt_delta = std::sqrt(delta);
00360 
00361       const real_type t_minus = (-b - sqrt_delta) / a;
00362       const real_type t_plus  = (-b + sqrt_delta) / a;
00363 
00364       const real_type t = (t_minus*t_plus<0) ? t_plus : t_minus;
00365 
00366       *cross = base + t*direction;
00367       return true;
00368     }
00369   }
00370 
00371 
00373   template<typename Real>
00374   void define_centered_ellipsoid(const Vec3<Real>&            x_axis,
00375                                  const Vec3<Real>&            y_axis,
00376                                  const Vec3<Real>&            z_axis,
00377                                  const Real                   x_radius,
00378                                  const Real                   y_radius,
00379                                  const Real                   z_radius,
00380                                  Square_matrix<3,Real>* const result){
00381 
00382     typedef Square_matrix<3,Real> matrix_type;
00383     
00384     matrix_type change; // = transpose of (x,y,z)
00385     change(0,0) = x_axis.x();
00386     change(0,1) = x_axis.y();
00387     change(0,2) = x_axis.z();
00388 
00389     change(1,0) = y_axis.x();
00390     change(1,1) = y_axis.y();
00391     change(1,2) = y_axis.z();
00392 
00393     change(2,0) = z_axis.x();
00394     change(2,1) = z_axis.y();
00395     change(2,2) = z_axis.z();
00396 
00397     matrix_type diag;
00398     diag(0,0) = 1/(x_radius*x_radius);
00399     diag(1,1) = 1/(y_radius*y_radius);
00400     diag(2,2) = 1/(z_radius*z_radius);
00401 
00402     *result = change.transpose() * diag * change;
00403   }
00404 
00405   
00406   template<typename Real>
00407   bool point_inside_ellipsoid(const Vec3<Real>&            point,
00408                               const Vec3<Real>&            center,
00409                               const Square_matrix<3,Real>& matrix){
00410 
00411     typedef Real            real_type;
00412     typedef Vec3<real_type> vector_type;
00413 
00414     const vector_type v = point - center;
00415     
00416     return (v*(matrix*v) < 1);
00417   }
00418 
00419 
00420 } // END OF namespace Geom_tools
00421 
00422 #endif

Generated on Fri Aug 20 15:03:52 2004 by doxygen1.2.18