PF_API 0.52

Code/Libs/Math_LIB/MPoint.h

Go to the documentation of this file.
00001 
00002 //    Copyright (C) 2004-2011 Dylan Blair
00003 //
00004 //    email: dblair@alumni.cs.utexas.edu
00005 //
00006 //    This library is free software; you can redistribute it and/or
00007 //    modify it under the terms of the GNU Lesser General Public
00008 //    License as published by the Free Software Foundation; either
00009 //    version 2.1 of the License, or (at your option) any later version.
00010 //
00011 //    This library is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 //    Lesser General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU Lesser General Public
00017 //    License along with this library; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021 #ifndef MPOINT_H
00022 #define MPOINT_H
00023 
00024 #include <string.h> //for memset()
00025 #include <algorithm> //for max()
00026 
00027 #include "MFun.h"
00028 
00029 namespace OpenSkyNet {
00030     namespace Math {
00032         template<class T=float, unsigned char U=3>
00033         class Point {
00034             const unsigned char _numDimensions;
00035         public:
00036             T _dimensions[U];
00037 
00038             Point(const T& x_=0, const T& y_=0, const T& z_=0) : _numDimensions(U) {
00039                 assert(U >= 1);
00040                 memset(_dimensions,0,sizeof(T)*U);
00041                 switch (_numDimensions) {
00042                     case 1:
00043                         _dimensions[0] = x_;
00044                     break;
00045                     case 2:
00046                         _dimensions[0] = x_;
00047                         _dimensions[1] = y_;
00048                     break;
00049                     default:
00050                         _dimensions[0] = x_;
00051                         _dimensions[1] = y_;
00052                         _dimensions[2] = z_;
00053                     break;
00054                 }
00055             }
00056 
00057             Point(const Point<T>& p_) : _numDimensions(U) {
00058                 for (unsigned char i = 0; i < _numDimensions; ++i)
00059                     _dimensions[i] = p_._dimensions[i];
00060             }
00061 
00064             inline unsigned char getNumDimensions() const { return _numDimensions; }
00065             inline T& x() { return _dimensions[0]; }
00066             inline T& y() { return _dimensions[1]; }
00067             inline T& z() { return _dimensions[2]; }
00068             inline T& r() { return _dimensions[0]; }
00069             inline T& g() { return _dimensions[1]; }
00070             inline T& b() { return _dimensions[2]; }
00071             inline T& a() { return _dimensions[3]; }
00072             inline T& operator[](int i_) { return _dimensions[i_]; }
00073             inline const T& x() const { return _dimensions[0]; }
00074             inline const T& y() const { return _dimensions[1]; }
00075             inline const T& z() const { return _dimensions[2]; }
00076             inline const T& r() const { return _dimensions[0]; }
00077             inline const T& g() const { return _dimensions[1]; }
00078             inline const T& b() const { return _dimensions[2]; }
00079             inline const T& a() const { return _dimensions[3]; }
00080             inline const T& operator[](int i_) const { return _dimensions[i_]; }
00082 
00086             inline Point<T> operator-() const {
00087                 Point<T> result(*this);
00088                 for (unsigned char i = 0; i < result._numDimensions; ++i)
00089                     result._dimensions[i] = -result._dimensions[i];
00090                 return result;
00091             }
00092 
00094             inline Point<T> getAbs() const {
00095                 Point<T> result(*this);
00096                 for (unsigned char i = 0; i < result._numDimensions; ++i)
00097                     if (result._dimensions[i] < 0)
00098                         result._dimensions[i] = -result._dimensions[i];
00099                 return result;
00100             }
00101 
00103             inline T getComponentSum() const {
00104                 T sum = 0;
00105                 for (unsigned char i = 0; i < _numDimensions; ++i)
00106                     sum += _dimensions[i];
00107                 return sum;
00108             }
00109 
00111             inline T getMax() const {
00112                 T max = _dimensions[0];
00113                 for (unsigned char i = 1; i < _numDimensions; ++i)
00114                     if (_dimensions[i] > max)
00115                         max = _dimensions[i];
00116                 return max;
00117             }
00118 
00120             inline T getMin() const {
00121                 T min = _dimensions[0];
00122                 for (unsigned char i = 1; i < _numDimensions; ++i)
00123                     if (_dimensions[i] < min)
00124                         min = _dimensions[i];
00125                 return min;
00126             }
00127 
00129             inline T getLenSqrd() const {
00130                 T length = 0;
00131                 for (unsigned char i = 0; i < _numDimensions; ++i)
00132                     length += _dimensions[i]*_dimensions[i];
00133                 return length;
00134             }
00135 
00137             inline T getLength() const { return (static_cast<T>(sqrt(getLenSqrd()))); }
00138 
00140             inline void normalize() {
00141                 T lensqrd = getLenSqrd();
00142                 if (lensqrd) {
00143                     T len = static_cast<T>(sqrt(lensqrd));
00144                     for (unsigned char i = 0; i < _numDimensions; ++i)
00145                         _dimensions[i] /= len;
00146                 }
00147             }
00149 
00153             inline bool equals(const Point<T>& rhs_, T radiusSqrd_) const {
00154                 if ((rhs_ - *this).getLenSqrd() > radiusSqrd_)
00155                     return false;
00156                 return true;
00157             }
00158 
00160             inline Point<T,U>& operator=(const Point<T,U>& rhs_) {
00161                 for (unsigned char i = 0; i < _numDimensions; ++i)
00162                     _dimensions[i] = rhs_._dimensions[i];
00163                 return *this;
00164             }
00165 
00167             inline Point<T>& operator+=(const Point<T>& rhs_) {
00168                 for (unsigned char i = 0; i < rhs_._numDimensions; ++i)
00169                     _dimensions[i] = _dimensions[i] + rhs_._dimensions[i];
00170                 return *this;
00171             }
00172 
00174             inline Point<T>& operator+=(const T& rhs_) {
00175                 for (unsigned char i = 0; i < _numDimensions; ++i)
00176                     _dimensions[i] = _dimensions[i] + rhs_;
00177                 return *this;
00178             }
00179 
00181             inline Point<T>& operator-=(const Point<T>& rhs_) { return (*this)+=(-rhs_); }
00182 
00184             inline Point<T>& operator-=(const T& rhs_) {
00185                 for (unsigned char i = 0; i < _numDimensions; ++i)
00186                     _dimensions[i] = _dimensions[i] - rhs_;
00187                 return *this;
00188             }
00189 
00191             inline Point<T>& operator*=(const T& rhs_) {
00192                 for (unsigned char i = 0; i < _numDimensions; ++i)
00193                     _dimensions[i] = _dimensions[i] * rhs_;
00194                 return *this;
00195             }
00196 
00198             inline Point<T> getCross3(const Point<T>& rhs_) const {
00199                 return Point<T>(y()*rhs_.z() - z()*rhs_.y(), z()*rhs_.x() - x()*rhs_.z(), x()*rhs_.y() - y()*rhs_.x());
00200             }
00201 
00203             inline T getDot3(const Point<T>& rhs_) const {
00204                 return (x()*rhs_.x() + y()*rhs_.y() + z()*rhs_.z());
00205             }
00206 
00208             inline Point<T> getReflection3(const Point<T>& n_) const {
00209                 Point<T> projection(n_ * getDot3(n_));
00210                 return *this - (projection * 2.f);
00211             }
00213         };
00214 
00215         extern const Math::Point<> g_origin;
00216         extern const Math::Point<> g_xAxis;
00217         extern const Math::Point<> g_yAxis;
00218         extern const Math::Point<> g_zAxis;
00219 
00221         template<class T, class U>
00222         inline bool operator==(const Point<T>& lhs_, const Point<U>& rhs_) {
00223             bool result = true;
00224             for (unsigned char i = 0; i < lhs_.getNumDimensions(); ++i) {
00225                 if (lhs_._dimensions[i] != rhs_._dimensions[i]) {
00226                     result = false;
00227                     break;
00228                 }
00229             }
00230             return result;
00231         }
00232 
00234         template<class T, class U>
00235         inline bool operator!=(const Point<T>& lhs_, const Point<U>& rhs_) { return (!(lhs_ == rhs_)); }
00236 
00238         template<class T, class U>
00239         inline Point<T> operator+(const Point<T>& lhs_, const Point<U>& rhs_) {
00240             unsigned char dimensToAdd = lhs_.getNumDimensions();
00241             Point<T> result;
00242             for (unsigned char i = 0; i < dimensToAdd; ++i)
00243                 result._dimensions[i] = lhs_._dimensions[i] + rhs_._dimensions[i];
00244             return result;
00245         }
00246 
00248         template<class T, class U>
00249         inline Point<T> operator-(const Point<T>& lhs_, const Point<U>& rhs_) { return (lhs_ + -rhs_); }
00250 
00252         template<class T, class U>
00253         inline Point<T> operator*(const Point<T>& lhs_, const Point<U>& rhs_) {
00254             unsigned char dimensToMul = lhs_.getNumDimensions();
00255             Point<T> result;
00256             for (unsigned char i = 0; i < dimensToMul; ++i)
00257                 result._dimensions[i] = lhs_._dimensions[i] * rhs_._dimensions[i];
00258             return result;
00259         }
00260 
00262         template<class T, class U>
00263         inline Point<T> operator/(const Point<T>& lhs_, const Point<U>& rhs_) {
00264             unsigned char dimensToDiv = lhs_.getNumDimensions();
00265             Point<T> result;
00266             for (unsigned char i = 0; i < dimensToDiv; ++i)
00267                 result._dimensions[i] = lhs_._dimensions[i] / rhs_._dimensions[i];
00268             return result;
00269         }
00270 
00272         template<class T, class U>
00273         inline Point<T> operator*(const Point<T>& lhs_, const U& rhs_) {
00274             Point<T> result;
00275             for (unsigned char i = 0; i < lhs_.getNumDimensions(); ++i)
00276                 result._dimensions[i] = lhs_._dimensions[i] * rhs_;
00277             return result;
00278         }
00279 
00281         template<class T, class U>
00282         inline Point<T> operator/(const Point<T>& lhs_, const U& rhs_) {
00283             Point<T> result;
00284             for (unsigned char i = 0; i < lhs_.getNumDimensions(); ++i)
00285                 result._dimensions[i] = lhs_._dimensions[i] / rhs_;
00286             return result;
00287         }
00288 
00290         template<class T, class U>
00291         inline T getLength(const Point<T>& lhs_, const Point<U>& rhs_) { return (rhs_ - lhs_).getLength(); }
00292 
00298         template<class T, class U>
00299         inline Point<T> interpolate(const Point<T>& lhs_, const Point<U>& rhs_, float amount_) {
00300             Math::clamp<float>(amount_);
00301             return Point<T>((lhs_ * (1.0f - amount_)) + (rhs_ * amount_));
00302         }
00303 
00311         inline Point<float,2> RandPointInOrOnCircle(float radius_) {
00312             Point<float,2> p;
00313             const float radiusSqrd = radius_ * radius_;
00314 
00315             //the probability of needing more than k tries is (1-PI/4)^k. For k=20, this is ~ 0.00000000000004
00316             for (int n = 0; n < 20; ++n) {
00317                 p.x() = radius_ * randNeg1Pos1();
00318                 p.y() = radius_ * randNeg1Pos1();
00319                 if (p.getLenSqrd() <= radiusSqrd)
00320                     return p;
00321             }
00322 
00323             float rads = 2.0f * PI * rand01();
00324             float dist = rand01() + rand01();
00325             if (dist > 1.f)
00326                 dist = 2.f - dist;
00327 
00328             p.x() = radius_ * dist * cosf(rads);
00329             p.y() = radius_ * dist * sinf(rads);
00330 
00331             return p;
00332         }
00333     }
00334 }
00335 
00336 #endif //MPOINT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines