library of assembled shared sources

http://lass.cocamware.com

vector_3d.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_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 /** Wrap index around range.
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 /** Wrap index around range.
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 /** A weird way to get back the same object
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 /** componentwise addition
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 /** componentwise subtraction
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 /** Componentwise multiplication.
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 /** Componentwise division.
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 /** add other to each component of this.
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 /** subtract other of each component of this.
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 /** multiply each component of this with other.
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 /** divide each component of this by other.
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 /** Return true if all the components are (exactly!) zero
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 /** Return true if at least one of the components is NaN
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 /** Return squared norm of vector.
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 /** Return norm of vector.
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 /** return a unit vector with same direction/sense as this vector.
00307  *
00308  * <i>The normalized vector of <b>X</b> is a vector in the same direction but with norm (length) 1.
00309  * It is denoted <b>X^</b> and given by <b>X^</b> = <b>X</b> / |<b>X</b>|</i>,
00310  * http://mathworld.wolfram.com/NormalizedVector.html.
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 /** return the reciprocal version of this vector
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 /** Project vector on this one
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 /** Reject vector from this one
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 /** apply a function to every component
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 /** Normalize vector.
00376  */
00377 template<typename T> inline
00378 void Vector3D<T>::normalize()
00379 {
00380     *this /= norm();
00381 }
00382 
00383 
00384 
00385 /** Random unit vector
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 /** dot product.
00406  *  @relates lass::prim::Vector3D
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 /** cross product
00417  *  @relates lass::prim::Vector3D
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 /** @relates lass::prim::Vector3D
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 /** @relates lass::prim::Vector3D
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 /** componentwise addition
00450  *  @relates lass::prim::Vector3D
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 /** componentwise subtraction
00463  *  @relates lass::prim::Vector3D
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 /** Componentwise multiplication
00476  *  @relates lass::prim::Vector3D
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 /** Componentwise division
00489  *  @relates lass::prim::Vector3D
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 /** add b to all components of a.
00502  *  @relates lass::prim::Vector3D
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 /** subtract b of all components of a.
00515  *  @relates lass::prim::Vector3D
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 /** muliply all components of a by b
00528  *  @relates lass::prim::Vector3D
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 /** divide all components of a by b
00541  *  @relates lass::prim::Vector3D
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 /** add a to all components of b
00554  *  @relates lass::prim::Vector3D
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 /** subtract a of all components of b
00567  *  @relates lass::prim::Vector3D
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 /** multiply all components of b with a
00580  *  @relates lass::prim::Vector3D
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 /** return a vector with, for each coordinate, the minimum value of @a a and @a b
00593  *  @relates lass::prim::Vector3D
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 /** return a vector with, for each coordinate, the maximum value of @a a and @a b
00604  *  @relates lass::prim::Vector3D
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 /** interpolate linearly between two vectors: a + t * (b - a)
00615  *  @relates lass::prim::Vector3D
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 /** @relates lass::prim::Vector3D
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 /** @relates lass::prim::Vector3D
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 /** @relates lass::prim::Vector3D
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

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