summaryrefslogtreecommitdiffstats
path: root/tdescreensaver/kdesavers/vec3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdescreensaver/kdesavers/vec3.cpp')
-rw-r--r--tdescreensaver/kdesavers/vec3.cpp105
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>;