Wm4DistLine3Segment3.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 "Wm4DistLine3Segment3.h"
00019
00020 namespace Wm4
00021 {
00022
00023 template <class Real>
00024 DistLine3Segment3<Real>::DistLine3Segment3 (const Line3<Real>& rkLine,
00025 const Segment3<Real>& rkSegment)
00026 :
00027 m_rkLine(rkLine),
00028 m_rkSegment(rkSegment)
00029 {
00030 }
00031
00032 template <class Real>
00033 const Line3<Real>& DistLine3Segment3<Real>::GetLine () const
00034 {
00035 return m_rkLine;
00036 }
00037
00038 template <class Real>
00039 const Segment3<Real>& DistLine3Segment3<Real>::GetSegment () const
00040 {
00041 return m_rkSegment;
00042 }
00043
00044 template <class Real>
00045 Real DistLine3Segment3<Real>::Get ()
00046 {
00047 Real fSqrDist = GetSquared();
00048 return Math<Real>::Sqrt(fSqrDist);
00049 }
00050
00051 template <class Real>
00052 Real DistLine3Segment3<Real>::GetSquared ()
00053 {
00054 Vector3<Real> kDiff = m_rkLine.Origin - m_rkSegment.Origin;
00055 Real fA01 = -m_rkLine.Direction.Dot(m_rkSegment.Direction);
00056 Real fB0 = kDiff.Dot(m_rkLine.Direction);
00057 Real fC = kDiff.SquaredLength();
00058 Real fDet = Math<Real>::FAbs((Real)1.0 - fA01*fA01);
00059 Real fB1, fS0, fS1, fSqrDist, fExtDet;
00060
00061 if (fDet >= Math<Real>::ZERO_TOLERANCE)
00062 {
00063
00064 fB1 = -kDiff.Dot(m_rkSegment.Direction);
00065 fS1 = fA01*fB0-fB1;
00066 fExtDet = m_rkSegment.Extent*fDet;
00067
00068 if (fS1 >= -fExtDet)
00069 {
00070 if (fS1 <= fExtDet)
00071 {
00072
00073
00074 Real fInvDet = ((Real)1.0)/fDet;
00075 fS0 = (fA01*fB1-fB0)*fInvDet;
00076 fS1 *= fInvDet;
00077 fSqrDist = fS0*(fS0+fA01*fS1+((Real)2.0)*fB0) +
00078 fS1*(fA01*fS0+fS1+((Real)2.0)*fB1)+fC;
00079 }
00080 else
00081 {
00082
00083
00084 fS1 = m_rkSegment.Extent;
00085 fS0 = -(fA01*fS1+fB0);
00086 fSqrDist = -fS0*fS0+fS1*(fS1+((Real)2.0)*fB1)+fC;
00087 }
00088 }
00089 else
00090 {
00091
00092
00093 fS1 = -m_rkSegment.Extent;
00094 fS0 = -(fA01*fS1+fB0);
00095 fSqrDist = -fS0*fS0+fS1*(fS1+((Real)2.0)*fB1)+fC;
00096 }
00097 }
00098 else
00099 {
00100
00101
00102 fS1 = (Real)0.0;
00103 fS0 = -fB0;
00104 fSqrDist = fB0*fS0+fC;
00105 }
00106
00107 m_kClosestPoint0 = m_rkLine.Origin + fS0*m_rkLine.Direction;
00108 m_kClosestPoint1 = m_rkSegment.Origin + fS1*m_rkSegment.Direction;
00109 m_fLineParameter = fS0;
00110 m_fSegmentParameter = fS1;
00111 return Math<Real>::FAbs(fSqrDist);
00112 }
00113
00114 template <class Real>
00115 Real DistLine3Segment3<Real>::Get (Real fT, const Vector3<Real>& rkVelocity0,
00116 const Vector3<Real>& rkVelocity1)
00117 {
00118 Vector3<Real> kMOrigin0 = m_rkLine.Origin + fT*rkVelocity0;
00119 Vector3<Real> kMOrigin1 = m_rkSegment.Origin + fT*rkVelocity1;
00120 Line3<Real> kMLine(kMOrigin0,m_rkLine.Direction);
00121 Segment3<Real> kMSegment(kMOrigin1,m_rkSegment.Direction,
00122 m_rkSegment.Extent);
00123 return DistLine3Segment3<Real>(kMLine,kMSegment).Get();
00124 }
00125
00126 template <class Real>
00127 Real DistLine3Segment3<Real>::GetSquared (Real fT,
00128 const Vector3<Real>& rkVelocity0, const Vector3<Real>& rkVelocity1)
00129 {
00130 Vector3<Real> kMOrigin0 = m_rkLine.Origin + fT*rkVelocity0;
00131 Vector3<Real> kMOrigin1 = m_rkSegment.Origin + fT*rkVelocity1;
00132 Line3<Real> kMLine(kMOrigin0,m_rkLine.Direction);
00133 Segment3<Real> kMSegment(kMOrigin1,m_rkSegment.Direction,
00134 m_rkSegment.Extent);
00135 return DistLine3Segment3<Real>(kMLine,kMSegment).GetSquared();
00136 }
00137
00138 template <class Real>
00139 Real DistLine3Segment3<Real>::GetLineParameter () const
00140 {
00141 return m_fLineParameter;
00142 }
00143
00144 template <class Real>
00145 Real DistLine3Segment3<Real>::GetSegmentParameter () const
00146 {
00147 return m_fSegmentParameter;
00148 }
00149
00150
00151
00152
00153
00154 template WM4_FOUNDATION_ITEM
00155 class DistLine3Segment3<float>;
00156
00157 template WM4_FOUNDATION_ITEM
00158 class DistLine3Segment3<double>;
00159
00160 }