diff options
Diffstat (limited to 'tdescreensaver/kdesavers/vec3.cpp')
-rw-r--r-- | tdescreensaver/kdesavers/vec3.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/tdescreensaver/kdesavers/vec3.cpp b/tdescreensaver/kdesavers/vec3.cpp new file mode 100644 index 00000000..c66730e5 --- /dev/null +++ b/tdescreensaver/kdesavers/vec3.cpp @@ -0,0 +1,105 @@ +//============================================================================ +// +// 3-dim real vector class +// $Id$ +// Copyright (C) 2004 Georg Drenkhahn +// +// This file is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +//============================================================================ + +#include <math.h> +#if !defined(NAN) +static inline double nan__() +{ + static const unsigned int one = 1; + static const bool BigEndian = (*((unsigned char *) &one) == 0); + + static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; + static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; + + return *( ( const double * )( BigEndian ? be_nan_bytes : le_nan_bytes ) ); +} +# define NAN (::nan__()) +#endif + +#include <config.h> + +#ifdef HAVE_NUMERIC_LIMITS +#include <limits> +#endif + +#include <cerrno> +#include "vec3.h" + +template<typename T> +vec3<T>& vec3<T>::normalize() +{ + T n = norm(*this); + if (n != 0) + { + (*this) /= n; + } + else + { + errno = EDOM; // indicate domain error + // TODO: throw an exception? + } + return *this; +} + +template<typename T> +vec3<T>& vec3<T>::rotate(const vec3<T>& r) +{ + T phi = norm(r); + if (phi != 0) + { + // part of vector which is parallel to r + vec3<T> par(r*(*this)/(r*r) * r); + // part of vector which is perpendicular to r + vec3<T> perp(*this - par); + // rotation direction, size of perp + vec3<T> rotdir(norm(perp) * normalized(crossprod(r,perp))); + *this = par + cos(phi)*perp + sin(phi)*rotdir; + } + return *this; +} + +/*--- static member functions ---*/ + +template<typename T> +T vec3<T>::cos_angle(const vec3<T>& a, const vec3<T>& b) +{ + T den = norm(a) * norm(b); + T ret = 0; + // if |a|=0 or |b|=0 then angle is not defined. We return NAN in this case. + if (den != 0.0) + { + ret = a*b/den; + } + else + { + errno = EDOM; // indicate domain error +#ifdef HAVE_NUMERIC_LIMITS + // TODO test + ret = std::numeric_limits<T>::quiet_NaN(); +#else + ret = NAN; // return NAN from ISO C99 +#endif + } + return ret; +} + +template<typename T> +T vec3<T>::angle(const vec3<T>& a, const vec3<T>& b, const vec3<T>& c) +{ + // if |a|=0 or |b|=0 then angle is not defined. We return NAN in this case. + T ang = vec3<T>::angle(a,b); + return (crossprod(a,b)*c<0) ? + T(2.*M_PI)-ang : ang; +} + +// explicite instantiation +template class vec3<double>; |