00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_VECTOR_3D_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_PRIM_VECTOR_3D_INL
00047
00048
00049
00050
00051 #include "vector_3d.h"
00052 #include "../num/basic_ops.h"
00053 #include "../num/distribution.h"
00054
00055
00056
00057 namespace lass
00058 {
00059
00060 namespace prim
00061 {
00062
00063
00064 template<typename T>
00065 Vector3D<T>::Vector3D():
00066 x(TNumTraits::zero),
00067 y(TNumTraits::zero),
00068 z(TNumTraits::zero)
00069 {
00070 }
00071
00072
00073
00074 template<typename T>
00075 Vector3D<T>::Vector3D(TParam x, TParam y, TParam z):
00076 x(x),
00077 y(y),
00078 z(z)
00079 {
00080 }
00081
00082
00083
00084 template <typename T>
00085 template <typename U>
00086 Vector3D<T>::Vector3D(const Vector3D<U>& other):
00087 x(static_cast<TValue>(other.x)),
00088 y(static_cast<TValue>(other.y)),
00089 z(static_cast<TValue>(other.z))
00090 {
00091 }
00092
00093
00094
00095 template <typename T>
00096 template <typename U>
00097 Vector3D<T>::Vector3D(const U& x, const U& y, const U& z):
00098 x(static_cast<TValue>(x)),
00099 y(static_cast<TValue>(y)),
00100 z(static_cast<TValue>(z))
00101 {
00102 }
00103
00104
00105
00106 template<typename T>
00107 typename Vector3D<T>::TConstReference Vector3D<T>::operator[](size_t index) const
00108 {
00109 LASS_ASSERT(index < dimension);
00110 return *(&x + index);
00111 }
00112
00113
00114
00115 template<typename T>
00116 typename Vector3D<T>::TReference Vector3D<T>::operator[](size_t index)
00117 {
00118 LASS_ASSERT(index < dimension);
00119 return *(&x + index);
00120 }
00121
00122
00123
00124
00125
00126 template<typename T>
00127 typename Vector3D<T>::TConstReference Vector3D<T>::at(signed index) const
00128 {
00129 return *(&x + num::mod(index, dimension));
00130 }
00131
00132
00133
00134
00135
00136 template<typename T>
00137 typename Vector3D<T>::TReference Vector3D<T>::at(signed index)
00138 {
00139 return *(&x + num::mod(index, dimension));
00140 }
00141
00142
00143
00144
00145
00146 template<typename T>
00147 const Vector3D<T>& Vector3D<T>::operator+() const
00148 {
00149 return *this;
00150 }
00151
00152
00153
00154 template<typename T>
00155 const Vector3D<T> Vector3D<T>::operator-() const
00156 {
00157 return Vector3D(-x, -y, -z);
00158 }
00159
00160
00161
00162
00163
00164 template<typename T> inline
00165 Vector3D<T>& Vector3D<T>::operator+=(const Vector3D<T>& other)
00166 {
00167 x += other.x;
00168 y += other.y;
00169 z += other.z;
00170 return *this;
00171 }
00172
00173
00174
00175
00176
00177 template<typename T>
00178 Vector3D<T>& Vector3D<T>::operator-=(const Vector3D<T>& other)
00179 {
00180 x -= other.x;
00181 y -= other.y;
00182 z -= other.z;
00183 return *this;
00184 }
00185
00186
00187
00188
00189
00190 template<typename T> inline
00191 Vector3D<T>& Vector3D<T>::operator*=(const Vector3D<T>& other)
00192 {
00193 x *= other.x;
00194 y *= other.y;
00195 z *= other.z;
00196 return *this;
00197 }
00198
00199
00200
00201
00202
00203 template<typename T> inline
00204 Vector3D<T>& Vector3D<T>::operator/=(const Vector3D<T>& other)
00205 {
00206 x /= other.x;
00207 y /= other.y;
00208 z /= other.z;
00209 return *this;
00210 }
00211
00212
00213
00214
00215
00216 template<typename T> inline
00217 Vector3D<T>& Vector3D<T>::operator+=(TParam other)
00218 {
00219 x += other;
00220 y += other;
00221 z += other;
00222 return *this;
00223 }
00224
00225
00226
00227
00228
00229 template<typename T> inline
00230 Vector3D<T>& Vector3D<T>::operator-=(TParam other)
00231 {
00232 x -= other;
00233 y -= other;
00234 z -= other;
00235 return *this;
00236 }
00237
00238
00239
00240
00241
00242 template<typename T> inline
00243 Vector3D<T>& Vector3D<T>::operator*=(TParam other)
00244 {
00245 x *= other;
00246 y *= other;
00247 z *= other;
00248 return *this;
00249 }
00250
00251
00252
00253
00254
00255 template<typename T> inline
00256 Vector3D<T>& Vector3D<T>::operator/=(TParam other)
00257 {
00258 x /= other;
00259 y /= other;
00260 z /= other;
00261 return *this;
00262 }
00263
00264
00265
00266
00267
00268 template<typename T> inline
00269 const bool Vector3D<T>::isZero() const
00270 {
00271 return x == TNumTraits::zero && y == TNumTraits::zero && z == TNumTraits::zero;
00272 }
00273
00274
00275
00276
00277
00278 template<typename T> inline
00279 const bool Vector3D<T>::isNaN() const
00280 {
00281 return num::isNaN(x) || num::isNaN(y) || num::isNaN(z);
00282 }
00283
00284
00285
00286
00287
00288 template<typename T> inline
00289 const typename Vector3D<T>::TValue Vector3D<T>::squaredNorm() const
00290 {
00291 return dot(*this, *this);
00292 }
00293
00294
00295
00296
00297
00298 template<typename T> inline
00299 const typename Vector3D<T>::TValue Vector3D<T>::norm() const
00300 {
00301 return num::sqrt(squaredNorm());
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 template<typename T>
00313 const Vector3D<T> Vector3D<T>::normal() const
00314 {
00315 Vector3D<T> result(*this);
00316 result.normalize();
00317 return result;
00318 }
00319
00320
00321
00322
00323
00324 template<typename T>
00325 const Vector3D<T> Vector3D<T>::reciprocal() const
00326 {
00327 Vector3D<T> result(TNumTraits::one, TNumTraits::one, TNumTraits::one);
00328 result /= *this;
00329 return result;
00330 }
00331
00332
00333
00334
00335
00336 template <typename T>
00337 const Vector3D<T> Vector3D<T>::project(const Vector3D<T>& other) const
00338 {
00339 Vector3D<T> result(*this);
00340 result *= dot(other, *this);
00341 result /= squaredNorm();
00342 return result;
00343 }
00344
00345
00346
00347
00348
00349 template<typename T> inline
00350 const Vector3D<T> Vector3D<T>::reject(const Vector3D<T>& other) const
00351 {
00352 return other - project(other);
00353 }
00354
00355
00356
00357 template<typename T> inline
00358 const Vector3D<T> Vector3D<T>::reflect(const Vector3D<T>& other) const
00359 {
00360 return 2 * project(other) - other;
00361 }
00362
00363
00364
00365
00366
00367 template <typename T>
00368 const Vector3D<T> Vector3D<T>::transform(T (*op)(T)) const
00369 {
00370 return Vector3D<T>(op(x), op(y), op(z));
00371 }
00372
00373
00374
00375
00376
00377 template<typename T> inline
00378 void Vector3D<T>::normalize()
00379 {
00380 *this /= norm();
00381 }
00382
00383
00384
00385
00386
00387 template <typename T>
00388 template <class RandomGenerator>
00389 Vector3D<T> Vector3D<T>::random(RandomGenerator& generator)
00390 {
00391 num::DistributionUniform<TValue, RandomGenerator> zGenerator(
00392 generator, -TNumTraits::one, TNumTraits::one);
00393 const TValue z = zGenerator();
00394 const TValue r = num::sqrt(1 - num::sqr(z));
00395
00396 num::DistributionUniform<TValue, RandomGenerator> thetaGenerator(
00397 generator, TNumTraits::zero, 2 * TNumTraits::pi);
00398 const TValue theta = thetaGenerator();
00399
00400 return Vector3D<T>(r * num::cos(theta), r * num::sin(theta), z);
00401 }
00402
00403
00404
00405
00406
00407
00408 template<typename T> inline
00409 typename Vector3D<T>::TValue dot(const Vector3D<T>& a, const Vector3D<T>& b)
00410 {
00411 return a.x * b.x + a.y * b.y + a.z * b.z;
00412 }
00413
00414
00415
00416
00417
00418
00419 template<typename T> inline
00420 Vector3D<T> cross(const Vector3D<T>& a, const Vector3D<T>& b)
00421 {
00422 return Vector3D<T>(a.y * b.z - a.z * b.y,
00423 a.z * b.x - a.x * b.z,
00424 a.x * b.y - a.y * b.x);
00425 }
00426
00427
00428
00429
00430
00431 template<typename T> inline
00432 bool operator==(const Vector3D<T>& a, const Vector3D<T>& b)
00433 {
00434 return a.x == b.x && a.y == b.y && a.z == b.z;
00435 }
00436
00437
00438
00439
00440
00441 template<typename T> inline
00442 bool operator!=(const Vector3D<T>& a, const Vector3D<T>& b)
00443 {
00444 return !(a == b);
00445 }
00446
00447
00448
00449
00450
00451
00452 template<typename T> inline
00453 Vector3D<T> operator+(const Vector3D<T>& a, const Vector3D<T>& b)
00454 {
00455 Vector3D<T> result(a);
00456 result += b;
00457 return result;
00458 }
00459
00460
00461
00462
00463
00464
00465 template<typename T> inline
00466 Vector3D<T> operator-(const Vector3D<T>& a, const Vector3D<T>& b)
00467 {
00468 Vector3D<T> result(a);
00469 result -= b;
00470 return result;
00471 }
00472
00473
00474
00475
00476
00477
00478 template<typename T> inline
00479 Vector3D<T> operator*(const Vector3D<T>& a, const Vector3D<T>& b)
00480 {
00481 Vector3D<T> result(a);
00482 result *= b;
00483 return result;
00484 }
00485
00486
00487
00488
00489
00490
00491 template<typename T> inline
00492 Vector3D<T> operator/(const Vector3D<T>& a, const Vector3D<T>& b)
00493 {
00494 Vector3D<T> result(a);
00495 result /= b;
00496 return result;
00497 }
00498
00499
00500
00501
00502
00503
00504 template<typename T> inline
00505 Vector3D<T> operator+(const Vector3D<T>& a, typename Vector3D<T>::TParam b)
00506 {
00507 Vector3D<T> result(a);
00508 result += b;
00509 return result;
00510 }
00511
00512
00513
00514
00515
00516
00517 template<typename T> inline
00518 Vector3D<T> operator-(const Vector3D<T>& a, typename Vector3D<T>::TParam b)
00519 {
00520 Vector3D<T> result(a);
00521 result -= b;
00522 return result;
00523 }
00524
00525
00526
00527
00528
00529
00530 template<typename T> inline
00531 Vector3D<T> operator*(const Vector3D<T>& a, typename Vector3D<T>::TParam b)
00532 {
00533 Vector3D<T> result(a);
00534 result *= b;
00535 return result;
00536 }
00537
00538
00539
00540
00541
00542
00543 template<typename T> inline
00544 Vector3D<T> operator/(const Vector3D<T>& a, typename Vector3D<T>::TParam b)
00545 {
00546 Vector3D<T> result(a);
00547 result /= b;
00548 return result;
00549 }
00550
00551
00552
00553
00554
00555
00556 template<typename T> inline
00557 Vector3D<T> operator+(typename Vector3D<T>::TParam a, const Vector3D<T>& b)
00558 {
00559 Vector3D<T> result(b);
00560 result += a;
00561 return result;
00562 }
00563
00564
00565
00566
00567
00568
00569 template<typename T> inline
00570 Vector3D<T> operator-(typename Vector3D<T>::TParam a, const Vector3D<T>& b)
00571 {
00572 Vector3D<T> result(-b);
00573 result += a;
00574 return result;
00575 }
00576
00577
00578
00579
00580
00581
00582 template<typename T> inline
00583 Vector3D<T> operator*(typename Vector3D<T>::TParam a, const Vector3D<T>& b)
00584 {
00585 Vector3D<T> result(b);
00586 result *= a;
00587 return result;
00588 }
00589
00590
00591
00592
00593
00594
00595 template<typename T>
00596 inline Vector3D<T> pointwiseMin(const Vector3D<T>& a, const Vector3D<T>& b)
00597 {
00598 return Vector3D<T>(std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z));
00599 }
00600
00601
00602
00603
00604
00605
00606 template<typename T>
00607 inline Vector3D<T> pointwiseMax(const Vector3D<T>& a, const Vector3D<T>& b)
00608 {
00609 return Vector3D<T>(std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z));
00610 }
00611
00612
00613
00614
00615
00616
00617 template<typename T>
00618 inline Vector3D<T> lerp(const Vector3D<T>& a, const Vector3D<T>& b, typename Vector3D<T>::TParam t)
00619 {
00620 Vector3D<T> result = b;
00621 result -= a;
00622 result *= t;
00623 result += a;
00624 return result;
00625 }
00626
00627
00628
00629
00630
00631 template<typename T, typename Char, typename Traits>
00632 std::basic_ostream<Char, Traits>& operator<<(
00633 std::basic_ostream<Char, Traits>& stream, const Vector3D<T>& b)
00634 {
00635 LASS_ENFORCE_STREAM(stream) << "(" << b.x << ", " << b.y << ", " << b.z << ")";
00636 return stream;
00637 }
00638
00639
00640
00641
00642
00643 template<typename T, typename Char, typename Traits>
00644 std::basic_istream<Char, Traits>& operator>>(
00645 std::basic_istream<Char, Traits>& stream, Vector3D<T>& b)
00646 {
00647 Vector3D<T> result;
00648
00649 char c = 0;
00650 stream >> c;
00651 if (c != '(')
00652 {
00653 stream.clear(std::ios::failbit);
00654 return stream;
00655 }
00656
00657 c = 0;
00658 stream >> result.x >> c;
00659 if (c != ',')
00660 {
00661 stream.clear(std::ios::failbit);
00662 return stream;
00663 }
00664
00665 c = 0;
00666 stream >> result.y >> c;
00667 if (c != ',')
00668 {
00669 stream.clear(std::ios::failbit);
00670 return stream;
00671 }
00672
00673 c = 0;
00674 stream >> result.z >> c;
00675 if (c != ')')
00676 {
00677 stream.clear(std::ios::failbit);
00678 return stream;
00679 }
00680
00681 b = result;
00682 return stream;
00683 }
00684
00685
00686
00687
00688
00689 template<typename T>
00690 io::XmlOStream& operator<<(io::XmlOStream& stream, const Vector3D<T>& b)
00691 {
00692 LASS_ENFORCE_STREAM(stream)
00693 << "<Vector3D>" << b.x << " " << b.y << " " << b.z << "</Vector3D>\n";
00694 return stream;
00695 }
00696
00697
00698
00699 }
00700
00701 }
00702
00703 #endif