library of assembled shared sources

http://lass.cocamware.com

vector_2d.inl

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
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 /** Wrap index around range.
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 /** Wrap index around range.
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 /** A weird way to get back the same object
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 /** componentwise addition
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 /** componentwise subtraction
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 /** Componentwise multiplication.
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 /** Componentwise division.
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 /** add other to each component of this.
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 /** subtract other of each component of this.
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 /** multiply each component of this with other.
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 /** divide each component of this by other.
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 /** Return true if all the components are (exactly!) zero
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 /** Return true if at least one of the components is NaN
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 /** Return squared norm of vector.
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 /** Return norm of vector.
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 /** return a unit vector with same direction/sense as this vector.
00292  *
00293  * <i>The normalized vector of <b>X</b> is a vector in the same direction but with norm (length) 1.
00294  * It is denoted <b>X^</b> and given by <b>X^</b> = <b>X</b> / |<b>X</b>|</i>,
00295  * http://mathworld.wolfram.com/NormalizedVector.html.
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 /** return the reciprocal version of this vector
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 /** return the vector perpendicular to this one, 90° to the left.
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 /** Project vector on this one
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 /** Project vector on this one
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 /** apply a function to every component
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 /** Normalize vector.
00371  */
00372 template<typename T> inline
00373 void Vector2D<T>::normalize()
00374 {
00375     *this /= norm();
00376 }
00377 
00378 
00379 
00380 /** Random unit vector
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 /** dot product.
00395  *  @relates lass::prim::Vector2D
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 /** returns cosine of angle between both vectors.
00406  *  @relates lass::prim::Vector2D
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 /** perp dot product (cross product for 2D vectors).
00417  *  @relates lass::prim::Vector2D
00418  *
00419  *  <i>The "perp dot product" for <b>a</b> and <b>b</b> vectors in the plane is a modification of
00420  *  the two-dimensional dot product in which a is replaced by the perpendicular vector rotated 90°
00421  *  to the left defined by Hill (1994)</i>, http://mathworld.wolfram.com/PerpDotProduct.html.
00422  *
00423  *  It reminds a lot to the 3D cross product, as its result is equal to the z-value of the
00424  *  cross product of a and b extended to 3D space by setting their z-value to 0:
00425  *  Vector3D<T> c = cross(Vector3D<T>(a.x, a.y, 0), Vector3D<T>(b.x, b.y, 0)).  We know of this
00426  *  that c.x and c.y are both zero, and that c.z equals the perp dot product between a and b.
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 /** @relates lass::prim::Vector2D
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 /** @relates lass::prim::Vector2D
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 /** componentwise addition
00457  *  @relates lass::prim::Vector2D
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 /** componentwise subtraction
00470  *  @relates lass::prim::Vector2D
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 /** Componentwise multiplication
00483  *  @relates lass::prim::Vector2D
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 /** Componentwise division
00496  *  @relates lass::prim::Vector2D
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 /** add b to all components of a.
00509  *  @relates lass::prim::Vector2D
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 /** subtract b of all components of a.
00522  *  @relates lass::prim::Vector2D
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 /** muliply all components of a by b
00535  *  @relates lass::prim::Vector2D
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 /** divide all components of a by b
00548  *  @relates lass::prim::Vector2D
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 /** add a to all components of b
00561  *  @relates lass::prim::Vector2D
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 /** subtract a of all components of b
00574  *  @relates lass::prim::Vector2D
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 /** multiply all components of b with a
00587  *  @relates lass::prim::Vector2D
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 /** return a vector with, for each coordinate, the minimum value of @a a and @a b
00600  *  @relates lass::prim::Vector2D
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 /** return a vector with, for each coordinate, the maximum value of @a a and @a b
00611  *  @relates lass::prim::Vector2D
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 /** interpolate linearly between two vectors: a + t * (b - a)
00622  *  @relates lass::prim::Vector2D
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 /** @relates lass::prim::Vector2D
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 /** @relates lass::prim::Vector2D
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 /** @relates lass::prim::Vector2D
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

Generated on Mon Nov 10 14:22:02 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo