//============================================================================ // // 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 #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 #ifdef HAVE_NUMERIC_LIMITS #include #endif #include #include "vec3.h" template vec3& vec3::normalize() { T n = norm(*this); if (n != 0) { (*this) /= n; } else { errno = EDOM; // indicate domain error // TODO: throw an exception? } return *this; } template vec3& vec3::rotate(const vec3& r) { T phi = norm(r); if (phi != 0) { // part of vector which is parallel to r vec3 par(r*(*this)/(r*r) * r); // part of vector which is perpendicular to r vec3 perp(*this - par); // rotation direction, size of perp vec3 rotdir(norm(perp) * normalized(crossprod(r,perp))); *this = par + cos(phi)*perp + sin(phi)*rotdir; } return *this; } /*--- static member functions ---*/ template T vec3::cos_angle(const vec3& a, const vec3& 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::quiet_NaN(); #else ret = NAN; // return NAN from ISO C99 #endif } return ret; } template T vec3::angle(const vec3& a, const vec3& b, const vec3& c) { // if |a|=0 or |b|=0 then angle is not defined. We return NAN in this case. T ang = vec3::angle(a,b); return (crossprod(a,b)*c<0) ? T(2.*M_PI)-ang : ang; } // explicite instantiation template class vec3;