Wm4DistLine3Triangle3.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Wm4FoundationPCH.h"
00018 #include "Wm4DistLine3Triangle3.h"
00019 #include "Wm4DistLine3Segment3.h"
00020
00021 namespace Wm4
00022 {
00023
00024 template <class Real>
00025 DistLine3Triangle3<Real>::DistLine3Triangle3 (const Line3<Real>& rkLine,
00026 const Triangle3<Real>& rkTriangle)
00027 :
00028 m_rkLine(rkLine),
00029 m_rkTriangle(rkTriangle)
00030 {
00031 }
00032
00033 template <class Real>
00034 const Line3<Real>& DistLine3Triangle3<Real>::GetLine () const
00035 {
00036 return m_rkLine;
00037 }
00038
00039 template <class Real>
00040 const Triangle3<Real>& DistLine3Triangle3<Real>::GetTriangle () const
00041 {
00042 return m_rkTriangle;
00043 }
00044
00045 template <class Real>
00046 Real DistLine3Triangle3<Real>::Get ()
00047 {
00048 Real fSqrDist = GetSquared();
00049 return Math<Real>::Sqrt(fSqrDist);
00050 }
00051
00052 template <class Real>
00053 Real DistLine3Triangle3<Real>::GetSquared ()
00054 {
00055
00056 Vector3<Real> kEdge0 = m_rkTriangle.V[1] - m_rkTriangle.V[0];
00057 Vector3<Real> kEdge1 = m_rkTriangle.V[2] - m_rkTriangle.V[0];
00058 Vector3<Real> kNormal = kEdge0.UnitCross(kEdge1);
00059 Real fNdD = kNormal.Dot(m_rkLine.Direction);
00060 if (Math<Real>::FAbs(fNdD) > Math<Real>::ZERO_TOLERANCE)
00061 {
00062
00063
00064 Vector3<Real> kDiff = m_rkLine.Origin - m_rkTriangle.V[0];
00065 Vector3<Real>& rkD = (Vector3<Real>&) m_rkLine.Direction;
00066 Vector3<Real> kU, kV;
00067 Vector3<Real>::GenerateComplementBasis(kU,kV,rkD);
00068 Real fUdE0 = kU.Dot(kEdge0);
00069 Real fUdE1 = kU.Dot(kEdge0);
00070 Real fUdDiff = kU.Dot(kDiff);
00071 Real fVdE0 = kV.Dot(kEdge0);
00072 Real fVdE1 = kV.Dot(kEdge0);
00073 Real fVdDiff = kV.Dot(kDiff);
00074 Real fInvDet = ((Real)1.0)/(fUdE0*fVdE1 - fUdE1*fVdE0);
00075
00076
00077 Real fB1 = (fVdE1*fUdDiff - fUdE1*fVdDiff)*fInvDet;
00078 Real fB2 = (fUdE0*fVdDiff - fVdE0*fUdDiff)*fInvDet;
00079 Real fB0 = (Real)1.0 - fB1 - fB2;
00080
00081 if (fB0 >= (Real)0.0 && fB1 >= (Real)0.0 && fB2 >= (Real)0.0)
00082 {
00083
00084 Real fDdE0 = rkD.Dot(kEdge0);
00085 Real fDdE1 = rkD.Dot(kEdge1);
00086 Real fDdDiff = m_rkLine.Direction.Dot(kDiff);
00087 m_fLineParameter = fB1*fDdE0 + fB2*fDdE1 - fDdDiff;
00088
00089
00090 m_afTriangleBary[0] = fB0;
00091 m_afTriangleBary[1] = fB1;
00092 m_afTriangleBary[2] = fB2;
00093
00094
00095 m_kClosestPoint0 = m_rkLine.Origin +
00096 m_fLineParameter*m_rkLine.Direction;
00097
00098 m_kClosestPoint1 = m_rkTriangle.V[0] + fB1*kEdge0 + fB2*kEdge1;
00099 return (Real)0.0;
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108 Real fSqrDist = Math<Real>::MAX_REAL;
00109 for (int i0 = 2, i1 = 0; i1 < 3; i0 = i1++)
00110 {
00111 Segment3<Real> kSeg;
00112 kSeg.Origin = ((Real)0.5)*(m_rkTriangle.V[i0] + m_rkTriangle.V[i1]);
00113 kSeg.Direction = m_rkTriangle.V[i1] - m_rkTriangle.V[i0];
00114 kSeg.Extent = ((Real)0.5)*kSeg.Direction.Normalize();
00115 DistLine3Segment3<Real> kLSDist(m_rkLine,kSeg);
00116 Real fSqrDistTmp = kLSDist.GetSquared();
00117 if (fSqrDistTmp < fSqrDist)
00118 {
00119 m_kClosestPoint0 = kLSDist.GetClosestPoint0();
00120 m_kClosestPoint1 = kLSDist.GetClosestPoint1();
00121 fSqrDist = fSqrDistTmp;
00122
00123 m_fLineParameter = kLSDist.GetLineParameter();
00124 Real fRatio = kLSDist.GetSegmentParameter()/kSeg.Extent;
00125 m_afTriangleBary[i0] = ((Real)0.5)*((Real)1.0 - fRatio);
00126 m_afTriangleBary[i1] = (Real)1.0 - m_afTriangleBary[i0];
00127 m_afTriangleBary[3-i0-i1] = (Real)0.0;
00128 }
00129 }
00130 return fSqrDist;
00131 }
00132
00133 template <class Real>
00134 Real DistLine3Triangle3<Real>::Get (Real fT, const Vector3<Real>& rkVelocity0,
00135 const Vector3<Real>& rkVelocity1)
00136 {
00137 Vector3<Real> kMOrigin = m_rkLine.Origin + fT*rkVelocity0;
00138 Vector3<Real> kMV0 = m_rkTriangle.V[0] + fT*rkVelocity1;
00139 Vector3<Real> kMV1 = m_rkTriangle.V[1] + fT*rkVelocity1;
00140 Vector3<Real> kMV2 = m_rkTriangle.V[2] + fT*rkVelocity1;
00141 Line3<Real> kMLine(kMOrigin,m_rkLine.Direction);
00142 Triangle3<Real> kMTriangle(kMV0,kMV1,kMV2);
00143 return DistLine3Triangle3<Real>(kMLine,kMTriangle).Get();
00144 }
00145
00146 template <class Real>
00147 Real DistLine3Triangle3<Real>::GetSquared (Real fT,
00148 const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1)
00149 {
00150 Vector3<Real> kMOrigin = m_rkLine.Origin + fT*rkVelocity0;
00151 Vector3<Real> kMV0 = m_rkTriangle.V[0] + fT*rkVelocity1;
00152 Vector3<Real> kMV1 = m_rkTriangle.V[1] + fT*rkVelocity1;
00153 Vector3<Real> kMV2 = m_rkTriangle.V[2] + fT*rkVelocity1;
00154 Line3<Real> kMLine(kMOrigin,m_rkLine.Direction);
00155 Triangle3<Real> kMTriangle(kMV0,kMV1,kMV2);
00156 return DistLine3Triangle3<Real>(kMLine,kMTriangle).GetSquared();
00157 }
00158
00159 template <class Real>
00160 Real DistLine3Triangle3<Real>::GetLineParameter () const
00161 {
00162 return m_fLineParameter;
00163 }
00164
00165 template <class Real>
00166 Real DistLine3Triangle3<Real>::GetTriangleBary (int i) const
00167 {
00168 assert(0 <= i && i < 3);
00169 return m_afTriangleBary[i];
00170 }
00171
00172
00173
00174
00175
00176 template WM4_FOUNDATION_ITEM
00177 class DistLine3Triangle3<float>;
00178
00179 template WM4_FOUNDATION_ITEM
00180 class DistLine3Triangle3<double>;
00181
00182 }