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
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
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
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
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
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
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
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;
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 }
00421
00422 #endif