basic/geometry/geo_rangesensor/MgcDistLin3Lin3.cpp

Go to the documentation of this file.
00001 
00002 // Magic Software, Inc.
00003 // http://www.magic-software.com
00004 // Copyright (c) 2000, All Rights Reserved
00005 //
00006 // Source code from Magic Software is supplied under the terms of a license
00007 // agreement and may not be copied or disclosed except in accordance with the
00008 // terms of that agreement.  The various license agreements may be found at
00009 // the Magic Software web site.  This file is subject to the license
00010 //
00011 // FREE SOURCE CODE
00012 // http://www.magic-software.com/License.html/free.pdf
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         // lines are not parallel
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         // lines are parallel, select any closest pair of points
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             // two interior points are closest, one on line and one on ray
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             // end point of ray and interior point of line are closest
00087             fS = -fB0/fA00;
00088             fT = 0.0;
00089             fSqrDist = fB0*fS+fC;
00090         }
00091     }
00092     else
00093     {
00094         // lines are parallel, closest pair with one point at ray origin
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                 // two interior points are closest, one on line and one on
00131                 // segment
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                 // end point e1 of segment and interior point of line are
00141                 // closest
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             // end point e0 of segment and interior point of line are closest
00151             fS = -fB0/fA00;
00152             fT = 0.0;
00153             fSqrDist = fB0*fS+fC;
00154         }
00155     }
00156     else
00157     {
00158         // lines are parallel, closest pair with one point at segment origin
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         // rays are not parallel
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 )  // region 0 (interior)
00195             {
00196                 // minimum at two interior points of rays
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  // region 3 (side)
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 )  // region 1 (side)
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  // region 2 (corner)
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         // rays are parallel
00262         if ( fA01 > 0.0 )
00263         {
00264             // opposite direction vectors
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             // same direction vectors
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         // ray and segment are not parallel
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 )  // region 0
00329                 {
00330                     // minimum at interior points of ray and segment
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  // region 1
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  // region 5
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 )  // region 4
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 )  // region 3
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  // region 2
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         // ray and segment are parallel
00451         if ( fA01 > 0.0 )
00452         {
00453             // opposite direction vectors
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             // same direction vectors
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         // line segments are not parallel
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 )  // region 0 (interior)
00520                     {
00521                         // minimum at two interior points of 3D lines
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  // region 3 (side)
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  // region 7 (side)
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 )  // region 1 (side)
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  // region 2 (corner)
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  // region 8 (corner)
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 )  // region 5 (side)
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  // region 4 (corner)
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   // region 6 (corner)
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         // line segments are parallel
00773         if ( fA01 > 0.0 )
00774         {
00775             // direction vectors form an obtuse angle
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             // direction vectors form an acute angle
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 //----------------------------------------------------------------------------

Generated on Sat Apr 1 21:30:31 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO