basic/geometry/geo_rangesensor/MgcIntrLin3Box3.cpp

Go to the documentation of this file.
00001 // Magic Software, Inc.
00002 // http://www.magic-software.com
00003 // Copyright (c) 2000, All Rights Reserved
00004 //
00005 // Source code from Magic Software is supplied under the terms of a license
00006 // agreement and may not be copied or disclosed except in accordance with the
00007 // terms of that agreement.  The various license agreements may be found at
00008 // the Magic Software web site.  This file is subject to the license
00009 //
00010 // FREE SOURCE CODE
00011 // http://www.magic-software.com/License/free.pdf
00012 
00013 #include "MgcIntrLin3Box3.h"
00014 
00015 //----------------------------------------------------------------------------
00016 bool MgcTestIntersection (const MgcSegment3& rkSegment, const MgcBox3& rkBox)
00017 {
00018     double fAWdU[3], fADdU[3], fAWxDdU[3], fRhs;
00019     MgcVector3 kSDir = 0.5*rkSegment.Direction();
00020     MgcVector3 kSCen = rkSegment.Origin() + kSDir;
00021 
00022     MgcVector3 kDiff = kSCen - rkBox.Center();
00023 
00024     fAWdU[0] = MgcMath::Abs(kSDir.Dot(rkBox.Axis(0)));
00025     fADdU[0] = MgcMath::Abs(kDiff.Dot(rkBox.Axis(0)));
00026     fRhs = rkBox.Extent(0) + fAWdU[0];
00027     if ( fADdU[0] > fRhs )
00028         return false;
00029 
00030     fAWdU[1] = MgcMath::Abs(kSDir.Dot(rkBox.Axis(1)));
00031     fADdU[1] = MgcMath::Abs(kDiff.Dot(rkBox.Axis(1)));
00032     fRhs = rkBox.Extent(1) + fAWdU[1];
00033     if ( fADdU[1] > fRhs )
00034         return false;
00035 
00036     fAWdU[2] = MgcMath::Abs(kSDir.Dot(rkBox.Axis(2)));
00037     fADdU[2] = MgcMath::Abs(kDiff.Dot(rkBox.Axis(2)));
00038     fRhs = rkBox.Extent(2) + fAWdU[2];
00039     if ( fADdU[2] > fRhs )
00040         return false;
00041 
00042     MgcVector3 kWxD = kSDir.Cross(kDiff);
00043 
00044     fAWxDdU[0] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(0)));
00045     fRhs = rkBox.Extent(1)*fAWdU[2] + rkBox.Extent(2)*fAWdU[1];
00046     if ( fAWxDdU[0] > fRhs )
00047         return false;
00048 
00049     fAWxDdU[1] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(1)));
00050     fRhs = rkBox.Extent(0)*fAWdU[2] + rkBox.Extent(2)*fAWdU[0];
00051     if ( fAWxDdU[1] > fRhs )
00052         return false;
00053 
00054     fAWxDdU[2] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(2)));
00055     fRhs = rkBox.Extent(0)*fAWdU[1] + rkBox.Extent(1)*fAWdU[0];
00056     if ( fAWxDdU[2] > fRhs )
00057         return false;
00058 
00059     return true;
00060 }
00061 //----------------------------------------------------------------------------
00062 bool MgcTestIntersection (const MgcRay3& rkRay, const MgcBox3& rkBox)
00063 {
00064     double fWdU[3], fAWdU[3], fDdU[3], fADdU[3], fAWxDdU[3], fRhs;
00065 
00066     MgcVector3 kDiff = rkRay.Origin() - rkBox.Center();
00067 
00068     fWdU[0] = rkRay.Direction().Dot(rkBox.Axis(0));
00069     fAWdU[0] = MgcMath::Abs(fWdU[0]);
00070     fDdU[0] = kDiff.Dot(rkBox.Axis(0));
00071     fADdU[0] = MgcMath::Abs(fDdU[0]);
00072     if ( fADdU[0] > rkBox.Extent(0) && fDdU[0]*fWdU[0] >= 0.0f )
00073         return false;
00074 
00075     fWdU[1] = rkRay.Direction().Dot(rkBox.Axis(1));
00076     fAWdU[1] = MgcMath::Abs(fWdU[1]);
00077     fDdU[1] = kDiff.Dot(rkBox.Axis(1));
00078     fADdU[1] = MgcMath::Abs(fDdU[1]);
00079     if ( fADdU[1] > rkBox.Extent(1) && fDdU[1]*fWdU[1] >= 0.0f )
00080         return false;
00081 
00082     fWdU[2] = rkRay.Direction().Dot(rkBox.Axis(2));
00083     fAWdU[2] = MgcMath::Abs(fWdU[2]);
00084     fDdU[2] = kDiff.Dot(rkBox.Axis(2));
00085     fADdU[2] = MgcMath::Abs(fDdU[2]);
00086     if ( fADdU[2] > rkBox.Extent(2) && fDdU[2]*fWdU[2] >= 0.0f )
00087         return false;
00088 
00089     MgcVector3 kWxD = rkRay.Direction().Cross(kDiff);
00090 
00091     fAWxDdU[0] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(0)));
00092     fRhs = rkBox.Extent(1)*fAWdU[2] + rkBox.Extent(2)*fAWdU[1];
00093     if ( fAWxDdU[0] > fRhs )
00094         return false;
00095 
00096     fAWxDdU[1] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(1)));
00097     fRhs = rkBox.Extent(0)*fAWdU[2] + rkBox.Extent(2)*fAWdU[0];
00098     if ( fAWxDdU[1] > fRhs )
00099         return false;
00100 
00101     fAWxDdU[2] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(2)));
00102     fRhs = rkBox.Extent(0)*fAWdU[1] + rkBox.Extent(1)*fAWdU[0];
00103     if ( fAWxDdU[2] > fRhs )
00104         return false;
00105 
00106     return true;
00107 }
00108 //----------------------------------------------------------------------------
00109 bool MgcTestIntersection (const MgcLine3& rkLine, const MgcBox3& rkBox)
00110 {
00111     double fAWdU[3], fAWxDdU[3], fRhs;
00112 
00113     MgcVector3 kDiff = rkLine.Origin() - rkBox.Center();
00114     MgcVector3 kWxD = rkLine.Direction().Cross(kDiff);
00115 
00116     fAWdU[1] = MgcMath::Abs(rkLine.Direction().Dot(rkBox.Axis(1)));
00117     fAWdU[2] = MgcMath::Abs(rkLine.Direction().Dot(rkBox.Axis(2)));
00118     fAWxDdU[0] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(0)));
00119     fRhs = rkBox.Extent(1)*fAWdU[2] + rkBox.Extent(2)*fAWdU[1];
00120     if ( fAWxDdU[0] > fRhs )
00121         return false;
00122 
00123     fAWdU[0] = MgcMath::Abs(rkLine.Direction().Dot(rkBox.Axis(0)));
00124     fAWxDdU[1] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(1)));
00125     fRhs = rkBox.Extent(0)*fAWdU[2] + rkBox.Extent(2)*fAWdU[0];
00126     if ( fAWxDdU[1] > fRhs )
00127         return false;
00128 
00129     fAWxDdU[2] = MgcMath::Abs(kWxD.Dot(rkBox.Axis(2)));
00130     fRhs = rkBox.Extent(0)*fAWdU[1] + rkBox.Extent(1)*fAWdU[0];
00131     if ( fAWxDdU[2] > fRhs )
00132         return false;
00133 
00134     return true;
00135 }
00136 //----------------------------------------------------------------------------
00137 static bool Clip (MgcReal fDenom, MgcReal fNumer, MgcReal& rfT0,
00138     MgcReal& rfT1)
00139 {
00140     // Return value is 'true' if line segment intersects the current test
00141     // plane.  Otherwise 'false' is returned in which case the line segment
00142     // is entirely clipped.
00143 
00144     if ( fDenom > 0.0 )
00145     {
00146         if ( fNumer > fDenom*rfT1 )
00147             return false;
00148         if ( fNumer > fDenom*rfT0 )
00149             rfT0 = fNumer/fDenom;
00150         return true;
00151     }
00152     else if ( fDenom < 0.0 )
00153     {
00154         if ( fNumer > fDenom*rfT0 )
00155             return false;
00156         if ( fNumer > fDenom*rfT1 )
00157             rfT1 = fNumer/fDenom;
00158         return true;
00159     }
00160     else
00161     {
00162         return fNumer <= 0.0;
00163     }
00164 }
00165 //----------------------------------------------------------------------------
00166 bool MgcFindIntersection (const MgcVector3& rkOrigin,
00167     const MgcVector3& rkDirection, const MgcReal afExtent[3], MgcReal& rfT0,
00168     MgcReal& rfT1)
00169 {
00170     MgcReal fSaveT0 = rfT0, fSaveT1 = rfT1;
00171 
00172     bool bNotEntirelyClipped =
00173         Clip(+rkDirection.x,-rkOrigin.x-afExtent[0],rfT0,rfT1) &&
00174         Clip(-rkDirection.x,+rkOrigin.x-afExtent[0],rfT0,rfT1) &&
00175         Clip(+rkDirection.y,-rkOrigin.y-afExtent[1],rfT0,rfT1) &&
00176         Clip(-rkDirection.y,+rkOrigin.y-afExtent[1],rfT0,rfT1) &&
00177         Clip(+rkDirection.z,-rkOrigin.z-afExtent[2],rfT0,rfT1) &&
00178         Clip(-rkDirection.z,+rkOrigin.z-afExtent[2],rfT0,rfT1);
00179 
00180     return bNotEntirelyClipped && ( rfT0 != fSaveT0 || rfT1 != fSaveT1 );
00181 }
00182 //----------------------------------------------------------------------------
00183 bool MgcFindIntersection (const MgcSegment3& rkSegment, const MgcBox3& rkBox,
00184     int& riQuantity, MgcVector3 akPoint[2])
00185 {
00186     // convert segment to box coordinates
00187     MgcVector3 kDiff = rkSegment.Origin() - rkBox.Center();
00188     MgcVector3 kOrigin(
00189         kDiff.Dot(rkBox.Axis(0)),
00190         kDiff.Dot(rkBox.Axis(1)),
00191         kDiff.Dot(rkBox.Axis(2))
00192     );
00193     MgcVector3 kDirection(
00194         rkSegment.Direction().Dot(rkBox.Axis(0)),
00195         rkSegment.Direction().Dot(rkBox.Axis(1)),
00196         rkSegment.Direction().Dot(rkBox.Axis(2))
00197     );
00198 
00199     MgcReal fT0 = 0.0, fT1 = 1.0;
00200     bool bIntersects = MgcFindIntersection(kOrigin,kDirection,rkBox.Extents(),
00201         fT0,fT1);
00202 
00203     if ( bIntersects )
00204     {
00205         if ( fT0 > 0.0 )
00206         {
00207             if ( fT1 < 1.0 )
00208             {
00209                 riQuantity = 2;
00210                 akPoint[0] = rkSegment.Origin() + fT0*rkSegment.Direction();
00211                 akPoint[1] = rkSegment.Origin() + fT1*rkSegment.Direction();
00212             }
00213             else
00214             {
00215                 riQuantity = 1;
00216                 akPoint[0] = rkSegment.Origin() + fT0*rkSegment.Direction();
00217             }
00218         }
00219         else  // fT0 == 0.0
00220         {
00221             if ( fT1 < 1.0 )
00222             {
00223                 riQuantity = 1;
00224                 akPoint[0] = rkSegment.Origin() + fT1*rkSegment.Direction();
00225             }
00226             else  // fT1 == 1.0
00227             {
00228                 // segment entirely in box
00229                 riQuantity = 0;
00230             }
00231         }
00232     }
00233     else
00234     {
00235         riQuantity = 0;
00236     }
00237 
00238     return bIntersects;
00239 }
00240 //----------------------------------------------------------------------------
00241 bool MgcFindIntersection (const MgcRay3& rkRay, const MgcBox3& rkBox,double &t)
00242 {
00243         //int riQuantity;
00244         //MgcVector3 akPoint[2];
00245     // convert ray to box coordinates
00246     MgcVector3 kDiff = rkRay.Origin() - rkBox.Center();
00247     MgcVector3 kOrigin(
00248         kDiff.Dot(rkBox.Axis(0)),
00249         kDiff.Dot(rkBox.Axis(1)),
00250         kDiff.Dot(rkBox.Axis(2))
00251     );
00252     MgcVector3 kDirection(
00253         rkRay.Direction().Dot(rkBox.Axis(0)),
00254         rkRay.Direction().Dot(rkBox.Axis(1)),
00255         rkRay.Direction().Dot(rkBox.Axis(2))
00256     );
00257 
00258     MgcReal fT0 = 0.0, fT1 = MgcMath::INFINITY;
00259     bool bIntersects = MgcFindIntersection(kOrigin,kDirection,rkBox.Extents(),
00260         fT0,fT1);
00261 
00262     if (( fT0 > 0.0 ) && ( fT0 < fT1 ))
00263     {
00264                 t = fT0;
00265         } else if ( fT1 > 0.0 )
00266         {
00267                 t = fT1;
00268         }
00269 
00270     return bIntersects;
00271 }
00272 //----------------------------------------------------------------------------
00273 bool MgcFindIntersection (const MgcLine3& rkLine, const MgcBox3& rkBox,
00274     int& riQuantity, MgcVector3 akPoint[2])
00275 {
00276     // convert line to box coordinates
00277     MgcVector3 kDiff = rkLine.Origin() - rkBox.Center();
00278     MgcVector3 kOrigin(
00279         kDiff.Dot(rkBox.Axis(0)),
00280         kDiff.Dot(rkBox.Axis(1)),
00281         kDiff.Dot(rkBox.Axis(2))
00282     );
00283     MgcVector3 kDirection(
00284         rkLine.Direction().Dot(rkBox.Axis(0)),
00285         rkLine.Direction().Dot(rkBox.Axis(1)),
00286         rkLine.Direction().Dot(rkBox.Axis(2))
00287     );
00288 
00289     MgcReal fT0 = -MgcMath::INFINITY, fT1 = MgcMath::INFINITY;
00290     bool bIntersects = MgcFindIntersection(kOrigin,kDirection,rkBox.Extents(),
00291         fT0,fT1);
00292 
00293     if ( bIntersects )
00294     {
00295         if ( fT0 != fT1 )
00296         {
00297             riQuantity = 2;
00298             akPoint[0] = rkLine.Origin() + fT0*rkLine.Direction();
00299             akPoint[1] = rkLine.Origin() + fT1*rkLine.Direction();
00300         }
00301         else
00302         {
00303             riQuantity = 1;
00304             akPoint[0] = rkLine.Origin() + fT0*rkLine.Direction();
00305         }
00306     }
00307     else
00308     {
00309         riQuantity = 0;
00310     }
00311 
00312     return bIntersects;
00313 }
00314 //----------------------------------------------------------------------------

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