arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

mathExt.h

Go to the documentation of this file.
00001 ///////////////////////////////////////////////////////////////////////////
00002 //              _____________  ______________________    __   __  _____
00003 //             /  ________  |  |   ___   ________   /   |  \ /  \   |
00004 //            |  |       |  |_ |  |_ |  |       /  /    \__  |      |
00005 //            |  |  ___  |  || |  || |  |      /  /        | |      |
00006 //            |  | |   \ |  || |  || |  |     /  /      \__/ \__/ __|__
00007 //            |  | |_@  ||  || |  || |  |    /  /          Institute
00008 //            |  |___/  ||  ||_|  || |  |   /  /_____________________
00009 //             \_______/  \______/ | |__|  /___________________________
00010 //                        |  |__|  |
00011 //                         \______/
00012 //                    University of Utah       
00013 //                           2002
00014 ///////////////////////////////////////////////////////////////////////////
00015 
00016 //mathExt.h
00017 //Joe Kniss
00018 // first shot at reworking mm.h
00019 
00020 #ifndef __MATH_EXTENSIONS_DOT_H
00021 #define __MATH_EXTENSIONS_DOT_H
00022 
00023 #include <iostream>
00024 #include <limits>
00025 #include "vec3.h"
00026 #include "quat.h"
00027 #include "mat3.h"
00028 
00029 #ifdef max
00030 #undef max
00031 #endif
00032 #ifdef min
00033 #undef min
00034 #endif
00035 
00036 namespace gutz {
00037 
00038 ///////////////////////////////////////////////////////////////////////////
00039 // type shorthand
00040 ///////////////////////////////////////////////////////////////////////////
00041 /*typedef unsigned char    uchar;
00042 typedef unsigned char      ubyte;
00043 typedef unsigned short     ushort;
00044 typedef unsigned int       uint;
00045 typedef unsigned long      ulong;
00046 #if __win32
00047 //typedef LARGE_INTEGER      llong;
00048 //typedef ULARGE_INTEGER     ullong;
00049 #else // __real_os
00050 typedef long long          llong;
00051 typedef unsigned long long ullong;
00052 #endif // __win32
00053 */
00054 
00055 ///////////////////////////////////////////////////////////////////////////
00056 ///@name usefull constants
00057 /// these are often missing from math.h
00058 //@{
00059 ///////////////////////////////////////////////////////////////////////////
00060 #ifndef M_E
00061 #define M_E        2.71828182845904523536 
00062 #endif
00063 #ifndef M_LOG2E
00064 #define M_LOG2E    1.44269504088896340736 
00065 #endif
00066 #ifndef M_LOG10E
00067 #define M_LOG10E   0.434294481903251827651 
00068 #endif
00069 #ifndef M_LN2
00070 #define M_LN2      0.693147180559945309417 
00071 #endif
00072 #ifndef M_LN10
00073 #define M_LN10     2.30258509299404568402 
00074 #endif
00075 #ifndef M_PI
00076 #define M_PI       3.14159265358979323846 
00077 #endif
00078 #ifndef M_PI_2
00079 #define M_PI_2     1.57079632679489661923 
00080 #endif
00081 #ifndef M_PI_4
00082 #define M_PI_4     0.785398163397448309616 
00083 #endif
00084 #ifndef M_1_PI
00085 #define M_1_PI     0.318309886183790671538 
00086 #endif
00087 #ifndef M_2_PI
00088 #define M_2_PI     0.636619772367581343076 
00089 #endif
00090 #ifndef M_2_SQRTPI
00091 #define M_2_SQRTPI 1.12837916709551257390 
00092 #endif
00093 #ifndef M_SQRT2
00094 #define M_SQRT2    1.41421356237309504880 
00095 #endif
00096 #ifndef M_SQRT1_2
00097 #define M_SQRT1_2  0.707106781186547524401 
00098 #endif
00099 ///@}
00100 
00101 ///////////////////////////////////////////////////////////////////////////
00102 //@name usefull operations & tests
00103 /// template inlines are better than #defines,
00104 /// - the value being used is not a function if it is not supposed to be \n
00105 ///   for instance,  #define blah(x) x + x + x + x  \n
00106 ///   if "x" is a function or complex expression it gets evaluated 4 times! \n
00107 ///   on the other hand template<class T> inline T blah(T x) { return x+x+x+x; } \n
00108 ///   has a well defined return type and behaves as though "x" is value not.
00109 /// - over loading makes sense
00110 /// - return value and usage are obvious
00111 ///@{
00112 
00113 ///////////////////////////////////////////////////////////////////////////
00114 /// clamp [0,1]
00115 template<class T>
00116 inline
00117 T clamp(const T &x) 
00118 { return (x > 0 ? ( x < 1 ? x : 1) : 0) ; }
00119 
00120 /// clamp [c,C]
00121 template<class L, class T, class U>
00122 inline
00123 T clamp(const L &c, const T &x, const U &C) 
00124 { return (x > c ? ( x < C ? x : C) : c) ;}
00125 
00126 ///////////////////////////////////////////////////////////////////////////
00127 /// gutz min, just min, but don't want confusion
00128 template<class T>
00129 inline
00130 T g_min(const T &x, const T &y) 
00131 { return (x > y ? y : x); }
00132 
00133 /// gutz max, just max, but don't want confusion
00134 template<class T>
00135 inline
00136 T g_max(const T &x, const T &y) 
00137 { return (x > y ? x : y); }
00138 
00139 ///////////////////////////////////////////////////////////////////////////
00140 /// gutz abs, just abs, ...
00141 template<class T>
00142 inline
00143 T g_abs(const T &x) 
00144 { return (x > 0 ? x : -x); }
00145 
00146 ///////////////////////////////////////////////////////////////////////////
00147 /// gutz sign, ...
00148 template<class T>
00149 inline
00150 double g_sgn(const T &x) 
00151 { return (x > 0 ? 1.0 : (x < 0 ? -1.0 : 0.0)); }
00152 
00153 ///////////////////////////////////////////////////////////////////////////
00154 /// conversions 
00155 #define RAD2DEG(x) (180.0/M_PI*(x))
00156 #define DEG2RAD(x) (M_PI/180.0*(x))
00157 #define SGN(x)     ((x)>0 ? 1.0 : ((x)<0 ? -1.0 : 0))
00158 #define SQ(x)      ((x)*(x))
00159 
00160 ///////////////////////////////////////////////////////////////////////////
00161 /// affine:
00162 /// given intervals [i,I], [o,O] and a value x which may or may not be
00163 /// inside [i,I], return the value y such that y stands in the same
00164 /// relationship to [o,O] that x does with [i,I].  Or:
00165 /// \code
00166 ///    y - o         x - i     
00167 ///   -------   =   -------
00168 ///    O - o         I - i
00169 /// \endcode
00170 /// It is the callers responsibility to make sure I-i and O-o are 
00171 /// both greater than zero
00172 ///
00173 /// you need to make sure the types for i, I, and x match and o and O match
00174 /// the type of o,O will be your return type \n
00175 /// TODO, maybe the divide should happen at "double" precision? I chose
00176 ///  float for speed :)
00177 template<class TI,         /// input type 
00178          class TO>         /// output type
00179 inline
00180 TO g_affine(const TI &i, const TI &x, const TI &I, const TO &o, const TO &O)
00181 {
00182    return TO((O - o)*(x - i)/float((I - i)) + o);
00183 }
00184 
00185 ///////////////////////////////////////////////////////////////////////////
00186 /// standard random float range [0,1]
00187 #ifndef DRAND48
00188 #define DRAND48 (rand()/(double)RAND_MAX)
00189 #endif
00190 
00191 ///////////////////////////////////////////////////////////////////////////
00192 /// generic 2D line intersect
00193 template< class T >
00194 inline
00195 T intersect2D(const T p1x, const T p1y, const T d1x, const T d1y,
00196               const T p2x, const T p2y, const T d2x, const T d2y)
00197 {
00198    /// [d1x, d1y] dot Perp([d2x,d2y])
00199    const T div = d1x * -d2y + d1y * d2x;
00200    if(!div) /// [d1x,d1y] and [d2x,d2y] are parallel
00201       return std::numeric_limits<T>::infinity();
00202    /// t = ( p2 dot(perp(d2)) - p1 dot(perp(d2)) )/ div
00203    return (p2x * -d2y + p2y * d2x - p1x * -d2y - p1y * d2x)/div;
00204    
00205    /// here is the original implementation (easier to understand)
00206    //const vec2<T> od(-r.d.y, r.d.x); /// ortho (perpendicular) to r.d
00207    //const T div = d.dot(od);  /// in direction dot r.d-perp
00208    //if(!div) /// in direction parallel to r.d-perp
00209    //   return std::numeric_limits<T>::infinity(); 
00210    //return (r.p.dot(od) - p.dot(od))/div; 
00211 }
00212 
00213 ///////////////////////////////////////////////////////////////////////////
00214 /// projection (vector-vector)
00215 ///  project p1 ONTO p2
00216 template< class T >
00217 inline
00218 vec3<T> project(const vec3<T> &p1, const vec3<T> &p2)
00219 {
00220    return p2/p2.dot(p2) * p2.dot(p1);
00221 }
00222 
00223 ///////////////////////////////////////////////////////////////////////////
00224 /// ray/plane intersection.
00225 ///  returns infinity if no hit
00226 template< class T >
00227 inline
00228 T intersectRayPlane(const vec3<T> &rpos, const vec3<T> &rdir,
00229                     const vec3<T> &ppos, const vec3<T> &pnorm)
00230 {
00231    const T rdDpn = rdir.dot(pnorm);
00232    if(!rdDpn) return std::numeric_limits<T>::max();
00233    return ( ppos.dot(pnorm) - rpos.dot(pnorm) )/rdDpn;
00234 }
00235 
00236 ///////////////////////////////////////////////////////////////////////////
00237 /// ray/sphere intersection.
00238 ///   returns infinity if no hit, otherwise returns a vec2 containing the
00239 ///   min and max t's for the intersection in that order
00240 template< class T >
00241 inline
00242 vec2<T> intersectRaySphere(const vec3<T> &rpos, const vec3<T> &rdir,
00243                            const vec3<T> &cent, const T r)
00244 {
00245    vec3<T> x = rpos - cent;
00246    T a = rdir.dot(rdir);
00247    T b = rdir.dot(x) * 2;
00248    T c = x.dot(x) - r*r;
00249    T d = b*b - 4*a*c;
00250    if( d <= 0 ) return vec2<T>(std::numeric_limits<T>::max());
00251    return vec2<T>((-b-sqrt(d))/(2*a), (-b+sqrt(d))/(2*a));
00252 }
00253 
00254 ///////////////////////////////////////////////////////////////////////////
00255 /// get the rotation that takes one axis to another,
00256 /// vectors are assumed to be PreNormalized
00257 template< class T >
00258 mat3<T> axis2axisPN(const vec3<T> &v1, const vec3<T> &v2)
00259 {
00260    vec3<T> axis = -v1.cross(v2);
00261    float theta = v1.dot(v2);
00262    if(theta > 0)
00263    {
00264       theta = T(M_PI - 2 * asin( (-v1-v2).norm()/2.0 ));
00265    }
00266    else
00267    {
00268       theta = T(2 * asin( (v1-v2).norm()/2.0 ));
00269    }
00270    return mat3<T>(theta,axis);
00271 }
00272 template< class T >
00273 mat3<T> axis2axis(const vec3<T> &v1, const vec3<T> &v2)
00274 {
00275    return axis2axisPN(v1/v1.norm(), v2/v2.norm());
00276 }
00277 
00278 ///@}
00279 
00280 ///////////////////////////////////////////////////////////////
00281 ///@name generic policies
00282 ///@{
00283 
00284 /// deep copies + delete data
00285 template<class T>
00286 struct OwnAllocPolicy {
00287    /// true = failure, false = success
00288    bool cpyVec(T *v, const T *c, int num) const
00289    {
00290       if(v) delVec(v);
00291       v = new T[num];
00292       if(!c) return true;
00293       for(int i=0; i<num; ++i)
00294          v[i] = c[i];
00295       return false;
00296    }
00297    void delVec(T *v) const { if(v) delete[] v; }
00298    void delVal(T *v) const { if(v) delete v; }
00299 };
00300 
00301 /// alias copies (shallow) + DON'T delete data
00302 template<class T>
00303 struct WrapAllocPolicy {
00304    bool cpyVec(T *v, T *c, int num) const
00305    {
00306       v = c;
00307       if(!c) return true;
00308       return false;
00309    }
00310    void delVec(T *v) const {}
00311    void delVal(T *v) const {}
00312 };
00313 
00314 ///@}
00315 /////////////////////////////////////////////////////////////////
00316 
00317 } //end namespace gutz
00318 
00319 
00320 #endif
00321 

Send questions, comments, and bug reports to:
jmk