00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "MgcDistLin3Lin3.h"
00015
00016 static const MgcReal gs_fTolerance = 1e-05;
00017
00018
00019 MgcReal MgcSqrDistance (const MgcLine3& rkLine0, const MgcLine3& rkLine1,
00020 MgcReal* pfLinP0, MgcReal* pfLinP1)
00021 {
00022 MgcVector3 kDiff = rkLine0.Origin() - rkLine1.Origin();
00023 MgcReal fA00 = rkLine0.Direction().SquaredLength();
00024 MgcReal fA01 = -rkLine0.Direction().Dot(rkLine1.Direction());
00025 MgcReal fA11 = rkLine1.Direction().SquaredLength();
00026 MgcReal fB0 = kDiff.Dot(rkLine0.Direction());
00027 MgcReal fC = kDiff.SquaredLength();
00028 MgcReal fDet = MgcMath::Abs(fA00*fA11-fA01*fA01);
00029 MgcReal fB1, fS, fT, fSqrDist;
00030
00031 if ( fDet >= gs_fTolerance )
00032 {
00033
00034 fB1 = -kDiff.Dot(rkLine1.Direction());
00035 MgcReal fInvDet = 1.0/fDet;
00036 fS = (fA01*fB1-fA11*fB0)*fInvDet;
00037 fT = (fA01*fB0-fA00*fB1)*fInvDet;
00038 fSqrDist = fS*(fA00*fS+fA01*fT+2.0*fB0) +
00039 fT*(fA01*fS+fA11*fT+2.0*fB1)+fC;
00040 }
00041 else
00042 {
00043
00044 fS = -fB0/fA00;
00045 fT = 0.0;
00046 fSqrDist = fB0*fS+fC;
00047 }
00048
00049 if ( pfLinP0 )
00050 *pfLinP0 = fS;
00051
00052 if ( pfLinP1 )
00053 *pfLinP1 = fT;
00054
00055 return MgcMath::Abs(fSqrDist);
00056 }
00057
00058 MgcReal MgcSqrDistance (const MgcLine3& rkLine, const MgcRay3& rkRay,
00059 MgcReal* pfLinP, MgcReal* pfRayP)
00060 {
00061 MgcVector3 kDiff = rkLine.Origin() - rkRay.Origin();
00062 MgcReal fA00 = rkLine.Direction().SquaredLength();
00063 MgcReal fA01 = -rkLine.Direction().Dot(rkRay.Direction());
00064 MgcReal fA11 = rkRay.Direction().SquaredLength();
00065 MgcReal fB0 = kDiff.Dot(rkLine.Direction());
00066 MgcReal fC = kDiff.SquaredLength();
00067 MgcReal fDet = MgcMath::Abs(fA00*fA11-fA01*fA01);
00068 MgcReal fB1, fS, fT, fSqrDist;
00069
00070 if ( fDet >= gs_fTolerance )
00071 {
00072 fB1 = -kDiff.Dot(rkRay.Direction());
00073 fT = fA01*fB0-fA00*fB1;
00074
00075 if ( fT >= 0.0 )
00076 {
00077
00078 MgcReal fInvDet = 1.0/fDet;
00079 fS = (fA01*fB1-fA11*fB0)*fInvDet;
00080 fT *= fInvDet;
00081 fSqrDist = fS*(fA00*fS+fA01*fT+2.0*fB0) +
00082 fT*(fA01*fS+fA11*fT+2.0*fB1)+fC;
00083 }
00084 else
00085 {
00086
00087 fS = -fB0/fA00;
00088 fT = 0.0;
00089 fSqrDist = fB0*fS+fC;
00090 }
00091 }
00092 else
00093 {
00094
00095 fS = -fB0/fA00;
00096 fT = 0.0;
00097 fSqrDist = fB0*fS+fC;
00098 }
00099
00100 if ( pfLinP )
00101 *pfLinP = fS;
00102
00103 if ( pfRayP )
00104 *pfRayP = fT;
00105
00106 return MgcMath::Abs(fSqrDist);
00107 }
00108
00109 MgcReal MgcSqrDistance (const MgcLine3& rkLine, const MgcSegment3& rkSeg,
00110 MgcReal* pfLinP, MgcReal* pfSegP)
00111 {
00112 MgcVector3 kDiff = rkLine.Origin() - rkSeg.Origin();
00113 MgcReal fA00 = rkLine.Direction().SquaredLength();
00114 MgcReal fA01 = -rkLine.Direction().Dot(rkSeg.Direction());
00115 MgcReal fA11 = rkSeg.Direction().SquaredLength();
00116 MgcReal fB0 = kDiff.Dot(rkLine.Direction());
00117 MgcReal fC = kDiff.SquaredLength();
00118 MgcReal fDet = MgcMath::Abs(fA00*fA11-fA01*fA01);
00119 MgcReal fB1, fS, fT, fSqrDist;
00120
00121 if ( fDet >= gs_fTolerance )
00122 {
00123 fB1 = -kDiff.Dot(rkSeg.Direction());
00124 fT = fA01*fB0-fA00*fB1;
00125
00126 if ( fT >= 0.0 )
00127 {
00128 if ( fT <= fDet )
00129 {
00130
00131
00132 MgcReal fInvDet = 1.0/fDet;
00133 fS = (fA01*fB1-fA11*fB0)*fInvDet;
00134 fT *= fInvDet;
00135 fSqrDist = fS*(fA00*fS+fA01*fT+2.0*fB0) +
00136 fT*(fA01*fS+fA11*fT+2.0*fB1)+fC;
00137 }
00138 else
00139 {
00140
00141
00142 MgcReal fTmp = fA01+fB0;
00143 fS = -fTmp/fA00;
00144 fT = 1.0;
00145 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
00146 }
00147 }
00148 else
00149 {
00150
00151 fS = -fB0/fA00;
00152 fT = 0.0;
00153 fSqrDist = fB0*fS+fC;
00154 }
00155 }
00156 else
00157 {
00158
00159 fS = -fB0/fA00;
00160 fT = 0.0;
00161 fSqrDist = fB0*fS+fC;
00162 }
00163
00164 if ( pfLinP )
00165 *pfLinP = fS;
00166
00167 if ( pfSegP )
00168 *pfSegP = fT;
00169
00170 return MgcMath::Abs(fSqrDist);
00171 }
00172
00173 MgcReal MgcSqrDistance (const MgcRay3& rkRay0, const MgcRay3& rkRay1,
00174 MgcReal* pfRayP0, MgcReal* pfRayP1)
00175 {
00176 MgcVector3 kDiff = rkRay0.Origin() - rkRay1.Origin();
00177 MgcReal fA00 = rkRay0.Direction().SquaredLength();
00178 MgcReal fA01 = -rkRay0.Direction().Dot(rkRay1.Direction());
00179 MgcReal fA11 = rkRay1.Direction().SquaredLength();
00180 MgcReal fB0 = kDiff.Dot(rkRay0.Direction());
00181 MgcReal fC = kDiff.SquaredLength();
00182 MgcReal fDet = MgcMath::Abs(fA00*fA11-fA01*fA01);
00183 MgcReal fB1, fS, fT, fSqrDist;
00184
00185 if ( fDet >= gs_fTolerance )
00186 {
00187
00188 fB1 = -kDiff.Dot(rkRay1.Direction());
00189 fS = fA01*fB1-fA11*fB0;
00190 fT = fA01*fB0-fA00*fB1;
00191
00192 if ( fS >= 0.0 )
00193 {
00194 if ( fT >= 0.0 )
00195 {
00196
00197 MgcReal fInvDet = 1.0/fDet;
00198 fS *= fInvDet;
00199 fT *= fInvDet;
00200 fSqrDist = fS*(fA00*fS+fA01*fT+2.0*fB0) +
00201 fT*(fA01*fS+fA11*fT+2.0*fB1)+fC;
00202 }
00203 else
00204 {
00205 fT = 0.0;
00206 if ( fB0 >= 0.0 )
00207 {
00208 fS = 0.0;
00209 fSqrDist = fC;
00210 }
00211 else
00212 {
00213 fS = -fB0/fA00;
00214 fSqrDist = fB0*fS+fC;
00215 }
00216 }
00217 }
00218 else
00219 {
00220 if ( fT >= 0.0 )
00221 {
00222 fS = 0.0;
00223 if ( fB1 >= 0.0 )
00224 {
00225 fT = 0.0;
00226 fSqrDist = fC;
00227 }
00228 else
00229 {
00230 fT = -fB1/fA11;
00231 fSqrDist = fB1*fT+fC;
00232 }
00233 }
00234 else
00235 {
00236 if ( fB0 < 0.0 )
00237 {
00238 fS = -fB0/fA00;
00239 fT = 0.0;
00240 fSqrDist = fB0*fS+fC;
00241 }
00242 else
00243 {
00244 fS = 0.0;
00245 if ( fB1 >= 0.0 )
00246 {
00247 fT = 0.0;
00248 fSqrDist = fC;
00249 }
00250 else
00251 {
00252 fT = -fB1/fA11;
00253 fSqrDist = fB1*fT+fC;
00254 }
00255 }
00256 }
00257 }
00258 }
00259 else
00260 {
00261
00262 if ( fA01 > 0.0 )
00263 {
00264
00265 fT = 0.0;
00266 if ( fB0 >= 0.0 )
00267 {
00268 fS = 0.0;
00269 fSqrDist = fC;
00270 }
00271 else
00272 {
00273 fS = -fB0/fA00;
00274 fSqrDist = fB0*fS+fC;
00275 }
00276 }
00277 else
00278 {
00279
00280 if ( fB0 >= 0.0 )
00281 {
00282 fB1 = -kDiff.Dot(rkRay1.Direction());
00283 fS = 0.0;
00284 fT = -fB1/fA11;
00285 fSqrDist = fB1*fT+fC;
00286 }
00287 else
00288 {
00289 fS = -fB0/fA00;
00290 fT = 0.0;
00291 fSqrDist = fB0*fS+fC;
00292 }
00293 }
00294 }
00295
00296 if ( pfRayP0 )
00297 *pfRayP0 = fS;
00298
00299 if ( pfRayP1 )
00300 *pfRayP1 = fT;
00301
00302 return MgcMath::Abs(fSqrDist);
00303 }
00304
00305 MgcReal MgcSqrDistance (const MgcRay3& rkRay, const MgcSegment3& rkSeg,
00306 MgcReal* pfRayP, MgcReal* pfSegP)
00307 {
00308 MgcVector3 kDiff = rkRay.Origin() - rkSeg.Origin();
00309 MgcReal fA00 = rkRay.Direction().SquaredLength();
00310 MgcReal fA01 = -rkRay.Direction().Dot(rkSeg.Direction());
00311 MgcReal fA11 = rkSeg.Direction().SquaredLength();
00312 MgcReal fB0 = kDiff.Dot(rkRay.Direction());
00313 MgcReal fC = kDiff.SquaredLength();
00314 MgcReal fDet = MgcMath::Abs(fA00*fA11-fA01*fA01);
00315 MgcReal fB1, fS, fT, fSqrDist, fTmp;
00316
00317 if ( fDet >= gs_fTolerance )
00318 {
00319
00320 fB1 = -kDiff.Dot(rkSeg.Direction());
00321 fS = fA01*fB1-fA11*fB0;
00322 fT = fA01*fB0-fA00*fB1;
00323
00324 if ( fS >= 0.0 )
00325 {
00326 if ( fT >= 0.0 )
00327 {
00328 if ( fT <= fDet )
00329 {
00330
00331 MgcReal fInvDet = 1.0/fDet;
00332 fS *= fInvDet;
00333 fT *= fInvDet;
00334 fSqrDist = fS*(fA00*fS+fA01*fT+2.0*fB0) +
00335 fT*(fA01*fS+fA11*fT+2.0*fB1)+fC;
00336 }
00337 else
00338 {
00339 fT = 1.0;
00340 if ( fB0 >= -fA01 )
00341 {
00342 fS = 0.0;
00343 fSqrDist = fA11+2.0*fB1+fC;
00344 }
00345 else
00346 {
00347 fTmp = fA01 + fB0;
00348 fS = -fTmp/fA00;
00349 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
00350 }
00351 }
00352 }
00353 else
00354 {
00355 fT = 0.0;
00356 if ( fB0 >= 0.0 )
00357 {
00358 fS = 0.0;
00359 fSqrDist = fC;
00360 }
00361 else
00362 {
00363 fS = -fB0/fA00;
00364 fSqrDist = fB0*fS+fC;
00365 }
00366 }
00367 }
00368 else
00369 {
00370 if ( fT <= 0.0 )
00371 {
00372 if ( fB0 < 0.0 )
00373 {
00374 fS = -fB0/fA00;
00375 fT = 0.0;
00376 fSqrDist = fB0*fS+fC;
00377 }
00378 else
00379 {
00380 fS = 0.0;
00381 if ( fB1 >= 0.0 )
00382 {
00383 fT = 0.0;
00384 fSqrDist = fC;
00385 }
00386 else if ( -fB1 >= fA11 )
00387 {
00388 fT = 1.0;
00389 fSqrDist = fA11+2.0*fB1+fC;
00390 }
00391 else
00392 {
00393 fT = -fB1/fA11;
00394 fSqrDist = fB1*fT+fC;
00395 }
00396 }
00397 }
00398 else if ( fT <= fDet )
00399 {
00400 fS = 0.0;
00401 if ( fB1 >= 0.0 )
00402 {
00403 fT = 0.0;
00404 fSqrDist = fC;
00405 }
00406 else if ( -fB1 >= fA11 )
00407 {
00408 fT = 1.0;
00409 fSqrDist = fA11+2.0*fB1+fC;
00410 }
00411 else
00412 {
00413 fT = -fB1/fA11;
00414 fSqrDist = fB1*fT+fC;
00415 }
00416 }
00417 else
00418 {
00419 fTmp = fA01+fB0;
00420 if ( fTmp < 0.0 )
00421 {
00422 fS = -fTmp/fA00;
00423 fT = 1.0;
00424 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
00425 }
00426 else
00427 {
00428 fS = 0.0;
00429 if ( fB1 >= 0.0 )
00430 {
00431 fT = 0.0;
00432 fSqrDist = fC;
00433 }
00434 else if ( -fB1 >= fA11 )
00435 {
00436 fT = 1.0;
00437 fSqrDist = fA11+2*fB1+fC;
00438 }
00439 else
00440 {
00441 fT = -fB1/fA11;
00442 fSqrDist = fB1*fT+fC;
00443 }
00444 }
00445 }
00446 }
00447 }
00448 else
00449 {
00450
00451 if ( fA01 > 0.0 )
00452 {
00453
00454 fT = 0.0;
00455 if ( fB0 >= 0.0 )
00456 {
00457 fS = 0.0;
00458 fSqrDist = fC;
00459 }
00460 else
00461 {
00462 fS = -fB0/fA00;
00463 fSqrDist = fB0*fS+fC;
00464 }
00465 }
00466 else
00467 {
00468
00469 fB1 = -kDiff.Dot(rkSeg.Direction());
00470 fT = 1.0;
00471 fTmp = fA01+fB0;
00472 if ( fTmp >= 0.0 )
00473 {
00474 fS = 0.0;
00475 fSqrDist = fA11+2.0*fB1+fC;
00476 }
00477 else
00478 {
00479 fS = -fTmp/fA00;
00480 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
00481 }
00482 }
00483 }
00484
00485 if ( pfRayP )
00486 *pfRayP = fS;
00487
00488 if ( pfSegP )
00489 *pfSegP = fT;
00490
00491 return MgcMath::Abs(fSqrDist);
00492 }
00493
00494 MgcReal MgcSqrDistance (const MgcSegment3& rkSeg0, const MgcSegment3& rkSeg1,
00495 MgcReal* pfSegP0, MgcReal* pfSegP1)
00496 {
00497 MgcVector3 kDiff = rkSeg0.Origin() - rkSeg1.Origin();
00498 MgcReal fA00 = rkSeg0.Direction().SquaredLength();
00499 MgcReal fA01 = -rkSeg0.Direction().Dot(rkSeg1.Direction());
00500 MgcReal fA11 = rkSeg1.Direction().SquaredLength();
00501 MgcReal fB0 = kDiff.Dot(rkSeg0.Direction());
00502 MgcReal fC = kDiff.SquaredLength();
00503 MgcReal fDet = MgcMath::Abs(fA00*fA11-fA01*fA01);
00504 MgcReal fB1, fS, fT, fSqrDist, fTmp;
00505
00506 if ( fDet >= gs_fTolerance )
00507 {
00508
00509 fB1 = -kDiff.Dot(rkSeg1.Direction());
00510 fS = fA01*fB1-fA11*fB0;
00511 fT = fA01*fB0-fA00*fB1;
00512
00513 if ( fS >= 0.0 )
00514 {
00515 if ( fS <= fDet )
00516 {
00517 if ( fT >= 0.0 )
00518 {
00519 if ( fT <= fDet )
00520 {
00521
00522 MgcReal fInvDet = 1.0/fDet;
00523 fS *= fInvDet;
00524 fT *= fInvDet;
00525 fSqrDist = fS*(fA00*fS+fA01*fT+2.0*fB0) +
00526 fT*(fA01*fS+fA11*fT+2.0*fB1)+fC;
00527 }
00528 else
00529 {
00530 fT = 1.0;
00531 fTmp = fA01+fB0;
00532 if ( fTmp >= 0.0 )
00533 {
00534 fS = 0.0;
00535 fSqrDist = fA11+2.0*fB1+fC;
00536 }
00537 else if ( -fTmp >= fA00 )
00538 {
00539 fS = 1.0;
00540 fSqrDist = fA00+fA11+fC+2.0*(fB1+fTmp);
00541 }
00542 else
00543 {
00544 fS = -fTmp/fA00;
00545 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
00546 }
00547 }
00548 }
00549 else
00550 {
00551 fT = 0.0;
00552 if ( fB0 >= 0.0 )
00553 {
00554 fS = 0.0;
00555 fSqrDist = fC;
00556 }
00557 else if ( -fB0 >= fA00 )
00558 {
00559 fS = 1.0;
00560 fSqrDist = fA00+2.0*fB0+fC;
00561 }
00562 else
00563 {
00564 fS = -fB0/fA00;
00565 fSqrDist = fB0*fS+fC;
00566 }
00567 }
00568 }
00569 else
00570 {
00571 if ( fT >= 0.0 )
00572 {
00573 if ( fT <= fDet )
00574 {
00575 fS = 1.0;
00576 fTmp = fA01+fB1;
00577 if ( fTmp >= 0.0 )
00578 {
00579 fT = 0.0;
00580 fSqrDist = fA00+2.0*fB0+fC;
00581 }
00582 else if ( -fTmp >= fA11 )
00583 {
00584 fT = 1.0;
00585 fSqrDist = fA00+fA11+fC+2.0*(fB0+fTmp);
00586 }
00587 else
00588 {
00589 fT = -fTmp/fA11;
00590 fSqrDist = fTmp*fT+fA00+2.0*fB0+fC;
00591 }
00592 }
00593 else
00594 {
00595 fTmp = fA01+fB0;
00596 if ( -fTmp <= fA00 )
00597 {
00598 fT = 1.0;
00599 if ( fTmp >= 0.0 )
00600 {
00601 fS = 0.0;
00602 fSqrDist = fA11+2.0*fB1+fC;
00603 }
00604 else
00605 {
00606 fS = -fTmp/fA00;
00607 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
00608 }
00609 }
00610 else
00611 {
00612 fS = 1.0;
00613 fTmp = fA01+fB1;
00614 if ( fTmp >= 0.0 )
00615 {
00616 fT = 0.0;
00617 fSqrDist = fA00+2.0*fB0+fC;
00618 }
00619 else if ( -fTmp >= fA11 )
00620 {
00621 fT = 1.0;
00622 fSqrDist = fA00+fA11+fC+2.0*(fB0+fTmp);
00623 }
00624 else
00625 {
00626 fT = -fTmp/fA11;
00627 fSqrDist = fTmp*fT+fA00+2.0*fB0+fC;
00628 }
00629 }
00630 }
00631 }
00632 else
00633 {
00634 if ( -fB0 < fA00 )
00635 {
00636 fT = 0.0;
00637 if ( fB0 >= 0.0 )
00638 {
00639 fS = 0.0;
00640 fSqrDist = fC;
00641 }
00642 else
00643 {
00644 fS = -fB0/fA00;
00645 fSqrDist = fB0*fS+fC;
00646 }
00647 }
00648 else
00649 {
00650 fS = 1.0;
00651 fTmp = fA01+fB1;
00652 if ( fTmp >= 0.0 )
00653 {
00654 fT = 0.0;
00655 fSqrDist = fA00+2.0*fB0+fC;
00656 }
00657 else if ( -fTmp >= fA11 )
00658 {
00659 fT = 1.0;
00660 fSqrDist = fA00+fA11+fC+2.0*(fB0+fTmp);
00661 }
00662 else
00663 {
00664 fT = -fTmp/fA11;
00665 fSqrDist = fTmp*fT+fA00+2.0*fB0+fC;
00666 }
00667 }
00668 }
00669 }
00670 }
00671 else
00672 {
00673 if ( fT >= 0.0 )
00674 {
00675 if ( fT <= fDet )
00676 {
00677 fS = 0.0;
00678 if ( fB1 >= 0.0 )
00679 {
00680 fT = 0.0;
00681 fSqrDist = fC;
00682 }
00683 else if ( -fB1 >= fA11 )
00684 {
00685 fT = 1.0;
00686 fSqrDist = fA11+2.0*fB1+fC;
00687 }
00688 else
00689 {
00690 fT = -fB1/fA11;
00691 fSqrDist = fB1*fT+fC;
00692 }
00693 }
00694 else
00695 {
00696 fTmp = fA01+fB0;
00697 if ( fTmp < 0.0 )
00698 {
00699 fT = 1.0;
00700 if ( -fTmp >= fA00 )
00701 {
00702 fS = 1.0;
00703 fSqrDist = fA00+fA11+fC+2.0*(fB1+fTmp);
00704 }
00705 else
00706 {
00707 fS = -fTmp/fA00;
00708 fSqrDist = fTmp*fS+fA11+2.0*fB1+fC;
00709 }
00710 }
00711 else
00712 {
00713 fS = 0.0;
00714 if ( fB1 >= 0.0 )
00715 {
00716 fT = 0.0;
00717 fSqrDist = fC;
00718 }
00719 else if ( -fB1 >= fA11 )
00720 {
00721 fT = 1.0;
00722 fSqrDist = fA11+2.0*fB1+fC;
00723 }
00724 else
00725 {
00726 fT = -fB1/fA11;
00727 fSqrDist = fB1*fT+fC;
00728 }
00729 }
00730 }
00731 }
00732 else
00733 {
00734 if ( fB0 < 0.0 )
00735 {
00736 fT = 0.0;
00737 if ( -fB0 >= fA00 )
00738 {
00739 fS = 1.0;
00740 fSqrDist = fA00+2.0*fB0+fC;
00741 }
00742 else
00743 {
00744 fS = -fB0/fA00;
00745 fSqrDist = fB0*fS+fC;
00746 }
00747 }
00748 else
00749 {
00750 fS = 0.0;
00751 if ( fB1 >= 0.0 )
00752 {
00753 fT = 0.0;
00754 fSqrDist = fC;
00755 }
00756 else if ( -fB1 >= fA11 )
00757 {
00758 fT = 1.0;
00759 fSqrDist = fA11+2.0*fB1+fC;
00760 }
00761 else
00762 {
00763 fT = -fB1/fA11;
00764 fSqrDist = fB1*fT+fC;
00765 }
00766 }
00767 }
00768 }
00769 }
00770 else
00771 {
00772
00773 if ( fA01 > 0.0 )
00774 {
00775
00776 if ( fB0 >= 00 )
00777 {
00778 fS = 0.0;
00779 fT = 0.0;
00780 fSqrDist = fC;
00781 }
00782 else if ( -fB0 <= fA00 )
00783 {
00784 fS = -fB0/fA00;
00785 fT = 0.0;
00786 fSqrDist = fB0*fS+fC;
00787 }
00788 else
00789 {
00790 fB1 = -kDiff.Dot(rkSeg1.Direction());
00791 fS = 1.0;
00792 fTmp = fA00+fB0;
00793 if ( -fTmp >= fA01 )
00794 {
00795 fT = 1.0;
00796 fSqrDist = fA00+fA11+fC+2.0*(fA01+fB0+fB1);
00797 }
00798 else
00799 {
00800 fT = -fTmp/fA01;
00801 fSqrDist = fA00+2.0*fB0+fC+fT*(fA11*fT+2.0*(fA01+fB1));
00802 }
00803 }
00804 }
00805 else
00806 {
00807
00808 if ( -fB0 >= fA00 )
00809 {
00810 fS = 1.0;
00811 fT = 0.0;
00812 fSqrDist = fA00+2.0*fB0+fC;
00813 }
00814 else if ( fB0 <= 0 )
00815 {
00816 fS = -fB0/fA00;
00817 fT = 0.0;
00818 fSqrDist = fB0*fS+fC;
00819 }
00820 else
00821 {
00822 fB1 = -kDiff.Dot(rkSeg1.Direction());
00823 fS = 0.0;
00824 if ( fB0 >= -fA01 )
00825 {
00826 fT = 1.0;
00827 fSqrDist = fA11+2.0*fB1+fC;
00828 }
00829 else
00830 {
00831 fT = -fB0/fA01;
00832 fSqrDist = fC+fT*(2.0*fB1+fA11*fT);
00833 }
00834 }
00835 }
00836 }
00837
00838 if ( pfSegP0 )
00839 *pfSegP0 = fS;
00840
00841 if ( pfSegP1 )
00842 *pfSegP1 = fT;
00843
00844 return MgcMath::Abs(fSqrDist);
00845 }
00846
00847 MgcReal MgcDistance (const MgcLine3& rkLine0, const MgcLine3& rkLine1,
00848 MgcReal* pfLinP0, MgcReal* pfLinP1)
00849 {
00850 return MgcMath::Sqrt(MgcSqrDistance(rkLine0,rkLine1,pfLinP0,pfLinP1));
00851 }
00852
00853 MgcReal MgcDistance (const MgcLine3& rkLine, const MgcRay3& rkRay,
00854 MgcReal* pfLinP, MgcReal* pfRayP)
00855 {
00856 return MgcMath::Sqrt(MgcSqrDistance(rkLine,rkRay,pfLinP,pfRayP));
00857 }
00858
00859 MgcReal MgcDistance (const MgcLine3& rkLine, const MgcSegment3& rkSeg,
00860 MgcReal* pfLinP, MgcReal* pfSegP)
00861 {
00862 return MgcMath::Sqrt(MgcSqrDistance(rkLine,rkSeg,pfLinP,pfSegP));
00863 }
00864
00865 MgcReal MgcDistance (const MgcRay3& rkRay0, const MgcRay3& rkRay1,
00866 MgcReal* pfRayP0, MgcReal* pfRayP1)
00867 {
00868 return MgcMath::Sqrt(MgcSqrDistance(rkRay0,rkRay1,pfRayP0,pfRayP1));
00869 }
00870
00871 MgcReal MgcDistance (const MgcRay3& rkRay, const MgcSegment3& rkSeg,
00872 MgcReal* pfRayP, MgcReal* pfSegP)
00873 {
00874 return MgcMath::Sqrt(MgcSqrDistance(rkRay,rkSeg,pfRayP,pfSegP));
00875 }
00876
00877 MgcReal MgcDistance (const MgcSegment3& rkSeg0, const MgcSegment3& rkSeg1,
00878 MgcReal* pfSegP0, MgcReal* pfSegP1)
00879 {
00880 return MgcMath::Sqrt(MgcSqrDistance(rkSeg0,rkSeg1,pfSegP0,pfSegP1));
00881 }
00882