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