Wm4Vector2.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 namespace Wm4
00018 {
00019
00020 template <class Real>
00021 Vector2<Real>::Vector2 ()
00022 {
00023
00024 }
00025
00026 template <class Real>
00027 Vector2<Real>::Vector2 (Real fX, Real fY)
00028 {
00029 m_afTuple[0] = fX;
00030 m_afTuple[1] = fY;
00031 }
00032
00033 template <class Real>
00034 Vector2<Real>::Vector2 (const Real* afTuple)
00035 {
00036 m_afTuple[0] = afTuple[0];
00037 m_afTuple[1] = afTuple[1];
00038 }
00039
00040 template <class Real>
00041 Vector2<Real>::Vector2 (const Vector2& rkV)
00042 {
00043 m_afTuple[0] = rkV.m_afTuple[0];
00044 m_afTuple[1] = rkV.m_afTuple[1];
00045 }
00046
00047 template <class Real>
00048 Vector2<Real>::operator const Real* () const
00049 {
00050 return m_afTuple;
00051 }
00052
00053 template <class Real>
00054 Vector2<Real>::operator Real* ()
00055 {
00056 return m_afTuple;
00057 }
00058
00059 template <class Real>
00060 Real Vector2<Real>::operator[] (int i) const
00061 {
00062 return m_afTuple[i];
00063 }
00064
00065 template <class Real>
00066 Real& Vector2<Real>::operator[] (int i)
00067 {
00068 return m_afTuple[i];
00069 }
00070
00071 template <class Real>
00072 Real Vector2<Real>::X () const
00073 {
00074 return m_afTuple[0];
00075 }
00076
00077 template <class Real>
00078 Real& Vector2<Real>::X ()
00079 {
00080 return m_afTuple[0];
00081 }
00082
00083 template <class Real>
00084 Real Vector2<Real>::Y () const
00085 {
00086 return m_afTuple[1];
00087 }
00088
00089 template <class Real>
00090 Real& Vector2<Real>::Y ()
00091 {
00092 return m_afTuple[1];
00093 }
00094
00095 template <class Real>
00096 Vector2<Real>& Vector2<Real>::operator= (const Vector2& rkV)
00097 {
00098 m_afTuple[0] = rkV.m_afTuple[0];
00099 m_afTuple[1] = rkV.m_afTuple[1];
00100 return *this;
00101 }
00102
00103 template <class Real>
00104 int Vector2<Real>::CompareArrays (const Vector2& rkV) const
00105 {
00106 return memcmp(m_afTuple,rkV.m_afTuple,2*sizeof(Real));
00107 }
00108
00109 template <class Real>
00110 bool Vector2<Real>::operator== (const Vector2& rkV) const
00111 {
00112 return CompareArrays(rkV) == 0;
00113 }
00114
00115 template <class Real>
00116 bool Vector2<Real>::operator!= (const Vector2& rkV) const
00117 {
00118 return CompareArrays(rkV) != 0;
00119 }
00120
00121 template <class Real>
00122 bool Vector2<Real>::operator< (const Vector2& rkV) const
00123 {
00124 return CompareArrays(rkV) < 0;
00125 }
00126
00127 template <class Real>
00128 bool Vector2<Real>::operator<= (const Vector2& rkV) const
00129 {
00130 return CompareArrays(rkV) <= 0;
00131 }
00132
00133 template <class Real>
00134 bool Vector2<Real>::operator> (const Vector2& rkV) const
00135 {
00136 return CompareArrays(rkV) > 0;
00137 }
00138
00139 template <class Real>
00140 bool Vector2<Real>::operator>= (const Vector2& rkV) const
00141 {
00142 return CompareArrays(rkV) >= 0;
00143 }
00144
00145 template <class Real>
00146 Vector2<Real> Vector2<Real>::operator+ (const Vector2& rkV) const
00147 {
00148 return Vector2(
00149 m_afTuple[0]+rkV.m_afTuple[0],
00150 m_afTuple[1]+rkV.m_afTuple[1]);
00151 }
00152
00153 template <class Real>
00154 Vector2<Real> Vector2<Real>::operator- (const Vector2& rkV) const
00155 {
00156 return Vector2(
00157 m_afTuple[0]-rkV.m_afTuple[0],
00158 m_afTuple[1]-rkV.m_afTuple[1]);
00159 }
00160
00161 template <class Real>
00162 Vector2<Real> Vector2<Real>::operator* (Real fScalar) const
00163 {
00164 return Vector2(
00165 fScalar*m_afTuple[0],
00166 fScalar*m_afTuple[1]);
00167 }
00168
00169 template <class Real>
00170 Vector2<Real> Vector2<Real>::operator/ (Real fScalar) const
00171 {
00172 Vector2 kQuot;
00173
00174 if (fScalar != (Real)0.0)
00175 {
00176 Real fInvScalar = ((Real)1.0)/fScalar;
00177 kQuot.m_afTuple[0] = fInvScalar*m_afTuple[0];
00178 kQuot.m_afTuple[1] = fInvScalar*m_afTuple[1];
00179 }
00180 else
00181 {
00182 kQuot.m_afTuple[0] = Math<Real>::MAX_REAL;
00183 kQuot.m_afTuple[1] = Math<Real>::MAX_REAL;
00184 }
00185
00186 return kQuot;
00187 }
00188
00189 template <class Real>
00190 Vector2<Real> Vector2<Real>::operator- () const
00191 {
00192 return Vector2(
00193 -m_afTuple[0],
00194 -m_afTuple[1]);
00195 }
00196
00197 template <class Real>
00198 Vector2<Real> operator* (Real fScalar, const Vector2<Real>& rkV)
00199 {
00200 return Vector2<Real>(
00201 fScalar*rkV[0],
00202 fScalar*rkV[1]);
00203 }
00204
00205 template <class Real>
00206 Vector2<Real>& Vector2<Real>::operator+= (const Vector2& rkV)
00207 {
00208 m_afTuple[0] += rkV.m_afTuple[0];
00209 m_afTuple[1] += rkV.m_afTuple[1];
00210 return *this;
00211 }
00212
00213 template <class Real>
00214 Vector2<Real>& Vector2<Real>::operator-= (const Vector2& rkV)
00215 {
00216 m_afTuple[0] -= rkV.m_afTuple[0];
00217 m_afTuple[1] -= rkV.m_afTuple[1];
00218 return *this;
00219 }
00220
00221 template <class Real>
00222 Vector2<Real>& Vector2<Real>::operator*= (Real fScalar)
00223 {
00224 m_afTuple[0] *= fScalar;
00225 m_afTuple[1] *= fScalar;
00226 return *this;
00227 }
00228
00229 template <class Real>
00230 Vector2<Real>& Vector2<Real>::operator/= (Real fScalar)
00231 {
00232 if (fScalar != (Real)0.0)
00233 {
00234 Real fInvScalar = ((Real)1.0)/fScalar;
00235 m_afTuple[0] *= fInvScalar;
00236 m_afTuple[1] *= fInvScalar;
00237 }
00238 else
00239 {
00240 m_afTuple[0] = Math<Real>::MAX_REAL;
00241 m_afTuple[1] = Math<Real>::MAX_REAL;
00242 }
00243
00244 return *this;
00245 }
00246
00247 template <class Real>
00248 Real Vector2<Real>::Length () const
00249 {
00250 return Math<Real>::Sqrt(
00251 m_afTuple[0]*m_afTuple[0] +
00252 m_afTuple[1]*m_afTuple[1]);
00253 }
00254
00255 template <class Real>
00256 Real Vector2<Real>::SquaredLength () const
00257 {
00258 return
00259 m_afTuple[0]*m_afTuple[0] +
00260 m_afTuple[1]*m_afTuple[1];
00261 }
00262
00263 template <class Real>
00264 Real Vector2<Real>::Dot (const Vector2& rkV) const
00265 {
00266 return
00267 m_afTuple[0]*rkV.m_afTuple[0] +
00268 m_afTuple[1]*rkV.m_afTuple[1];
00269 }
00270
00271 template <class Real>
00272 Real Vector2<Real>::Normalize ()
00273 {
00274 Real fLength = Length();
00275
00276 if (fLength > Math<Real>::ZERO_TOLERANCE)
00277 {
00278 Real fInvLength = ((Real)1.0)/fLength;
00279 m_afTuple[0] *= fInvLength;
00280 m_afTuple[1] *= fInvLength;
00281 }
00282 else
00283 {
00284 fLength = (Real)0.0;
00285 m_afTuple[0] = (Real)0.0;
00286 m_afTuple[1] = (Real)0.0;
00287 }
00288
00289 return fLength;
00290 }
00291
00292 template <class Real>
00293 Vector2<Real> Vector2<Real>::Perp () const
00294 {
00295 return Vector2(m_afTuple[1],-m_afTuple[0]);
00296 }
00297
00298 template <class Real>
00299 Vector2<Real> Vector2<Real>::UnitPerp () const
00300 {
00301 Vector2 kPerp(m_afTuple[1],-m_afTuple[0]);
00302 kPerp.Normalize();
00303 return kPerp;
00304 }
00305
00306 template <class Real>
00307 Real Vector2<Real>::DotPerp (const Vector2& rkV) const
00308 {
00309 return m_afTuple[0]*rkV.m_afTuple[1] - m_afTuple[1]*rkV.m_afTuple[0];
00310 }
00311
00312 template <class Real>
00313 void Vector2<Real>::GetBarycentrics (const Vector2& rkV0, const Vector2& rkV1,
00314 const Vector2& rkV2, Real afBary[3]) const
00315 {
00316
00317 Vector2 akDiff[3] =
00318 {
00319 rkV0 - rkV2,
00320 rkV1 - rkV2,
00321 *this - rkV2
00322 };
00323
00324
00325
00326
00327
00328 Real fMax = (Real)0.0;
00329 int i;
00330 for (i = 0; i < 2; i++)
00331 {
00332 for (int j = 0; j < 2; j++)
00333 {
00334 Real fValue = Math<Real>::FAbs(akDiff[i][j]);
00335 if (fValue > fMax)
00336 {
00337 fMax = fValue;
00338 }
00339 }
00340 }
00341
00342
00343 if (fMax > (Real)1.0)
00344 {
00345 Real fInvMax = ((Real)1.0)/fMax;
00346 for (i = 0; i < 3; i++)
00347 {
00348 akDiff[i] *= fInvMax;
00349 }
00350 }
00351
00352 Real fDet = akDiff[0].DotPerp(akDiff[1]);
00353 if (Math<Real>::FAbs(fDet) > Math<Real>::ZERO_TOLERANCE)
00354 {
00355 Real fInvDet = ((Real)1.0)/fDet;
00356 afBary[0] = akDiff[2].DotPerp(akDiff[1])*fInvDet;
00357 afBary[1] = akDiff[0].DotPerp(akDiff[2])*fInvDet;
00358 afBary[2] = (Real)1.0 - afBary[0] - afBary[1];
00359 }
00360 else
00361 {
00362
00363
00364 Vector2 kE2 = rkV0 - rkV1;
00365 Real fMaxSqrLength = kE2.SquaredLength();
00366 int iMaxIndex = 2;
00367 Real fSqrLength = akDiff[1].SquaredLength();
00368 if (fSqrLength > fMaxSqrLength)
00369 {
00370 iMaxIndex = 1;
00371 fMaxSqrLength = fSqrLength;
00372 }
00373 fSqrLength = akDiff[0].SquaredLength();
00374 if (fSqrLength > fMaxSqrLength)
00375 {
00376 iMaxIndex = 0;
00377 fMaxSqrLength = fSqrLength;
00378 }
00379
00380 if (fMaxSqrLength > Math<Real>::ZERO_TOLERANCE)
00381 {
00382 Real fInvSqrLength = ((Real)1.0)/fMaxSqrLength;
00383 if (iMaxIndex == 0)
00384 {
00385
00386 afBary[0] = akDiff[2].Dot(akDiff[0])*fInvSqrLength;
00387 afBary[1] = (Real)0.0;
00388 afBary[2] = (Real)1.0 - afBary[0];
00389 }
00390 else if (iMaxIndex == 1)
00391 {
00392
00393 afBary[0] = (Real)0.0;
00394 afBary[1] = akDiff[2].Dot(akDiff[1])*fInvSqrLength;
00395 afBary[2] = (Real)1.0 - afBary[1];
00396 }
00397 else
00398 {
00399
00400 akDiff[2] = *this - rkV1;
00401 afBary[0] = akDiff[2].Dot(kE2)*fInvSqrLength;
00402 afBary[1] = (Real)1.0 - afBary[0];
00403 afBary[2] = (Real)0.0;
00404 }
00405 }
00406 else
00407 {
00408
00409 afBary[0] = ((Real)1.0)/(Real)3.0;
00410 afBary[1] = afBary[0];
00411 afBary[2] = afBary[0];
00412 }
00413 }
00414 }
00415
00416 template <class Real>
00417 void Vector2<Real>::Orthonormalize (Vector2& rkU, Vector2& rkV)
00418 {
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 rkU.Normalize();
00430
00431
00432 Real fDot0 = rkU.Dot(rkV);
00433 rkV -= rkU*fDot0;
00434 rkV.Normalize();
00435 }
00436
00437 template <class Real>
00438 void Vector2<Real>::GenerateOrthonormalBasis (Vector2& rkU, Vector2& rkV)
00439 {
00440 rkV.Normalize();
00441 rkU = rkV.Perp();
00442 }
00443
00444 template <class Real>
00445 void Vector2<Real>::ComputeExtremes (int iVQuantity, const Vector2* akPoint,
00446 Vector2& rkMin, Vector2& rkMax)
00447 {
00448 assert(iVQuantity > 0 && akPoint);
00449
00450 rkMin = akPoint[0];
00451 rkMax = rkMin;
00452 for (int i = 1; i < iVQuantity; i++)
00453 {
00454 const Vector2<Real>& rkPoint = akPoint[i];
00455 for (int j = 0; j < 2; j++)
00456 {
00457 if (rkPoint[j] < rkMin[j])
00458 {
00459 rkMin[j] = rkPoint[j];
00460 }
00461 else if (rkPoint[j] > rkMax[j])
00462 {
00463 rkMax[j] = rkPoint[j];
00464 }
00465 }
00466 }
00467 }
00468
00469 template <class Real>
00470 std::ostream& operator<< (std::ostream& rkOStr, const Vector2<Real>& rkV)
00471 {
00472 return rkOStr << rkV.X() << ' ' << rkV.Y();
00473 }
00474
00475 }