Point.inl

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   Point.inl
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @date   Fall 2008
00005    
00006    @brief
00007       Provides basic functionality for a homogenous Point
00008    <!-------------------------------------------------------------------->**/
00009 
00010 #ifndef POINT_INL_
00011 #define POINT_INL_
00012 
00013 #include <iostream>
00014 using namespace std;
00015 
00016 
00017 // Constructors
00018 // ------------
00019 
00020 // Expects N arguments of type T
00021 // (srcData is a pointer to an N-length array of type T)
00022 template <unsigned N, typename T>
00023 inline Point<N, T>::Point(const T *srcData) {
00024    memcpy(data, srcData, POINT_SIZE);
00025    
00026    data[N - 1] = 1;
00027 }
00028 
00029 // Constructs an zero Point
00030 template <unsigned N, typename T>
00031 inline Point<N, T>::Point() {
00032    bzero(data, POINT_SIZE);
00033    
00034    data[N - 1] = 1;
00035 }
00036 
00037 // Copy Constructor; copies the underlying data from v to this point
00038 template <unsigned N, typename T>
00039 inline Point<N, T>::Point(const Point<N, T> &v) {
00040    memcpy(data, v.data, POINT_SIZE);
00041 }
00042 
00043 
00044 // Accessor Operators
00045 // ------------------
00046 
00047 // @returns a const reference to the element at the given index
00048 template <unsigned N, typename T>
00049 inline const T &Point<N, T>::operator[](const unsigned index) const {
00050    ASSERT(index < N);
00051    
00052    return data[index];
00053 }
00054 
00055 // @returns a reference to the element at the given index
00056 // @note changes to the returned element will affect this point
00057 template <unsigned N, typename T>
00058 inline       T &Point<N, T>::operator[](const unsigned index) {
00059    ASSERT(index < N);
00060    
00061    return data[index];
00062 }
00063 
00064 // @returns a pointer to the underlying data (N-length array of type T)
00065 template <unsigned N, typename T>
00066 inline const T *Point<N, T>::operator* () const {
00067    return (T*)this;
00068 }
00069 
00070 // @returns a pointer to the underlying data (N-length array of type T)
00071 template <unsigned N, typename T>
00072 inline       T *Point<N, T>::operator* () {
00073    return (T*)this;
00074 }
00075 
00076 
00077 // Equality Operators
00078 // ------------------
00079 template <unsigned N, typename T>
00080 inline       bool       Point<N, T>::operator==(const Point<N, T> &v) const
00081 {
00082    for(unsigned i = N; i--;)
00083       if (NEQ(data[i], v.data[i]))
00084          return false;
00085    
00086    return true;
00087 }
00088 
00089 template <unsigned N, typename T>
00090 inline       bool       Point<N, T>::operator!=(const Point<N, T> &v) const 
00091 {
00092    return !((*this) == v);
00093 }
00094 
00095 // Mutator Operators
00096 // -----------------
00097 template <unsigned N, typename T>
00098 inline       Point<N, T> &Point<N, T>::operator =(const Point<N, T> &v)
00099 {
00100    memcpy(data, v.data, POINT_SIZE);
00101    
00102    return *this;
00103 }
00104 
00105 template <unsigned N, typename T>
00106 inline       Point<N, T> &Point<N, T>::operator+=(const Vector<N - 1, T> &rhs)
00107 {
00108    for(unsigned i = N - 1; i--;)
00109       data[i] += rhs.data[i];
00110    
00111    return *this;
00112 }
00113 
00114 template <unsigned N, typename T>
00115 inline       Point<N, T> &Point<N, T>::operator-=(const Vector<N - 1, T> &rhs)
00116 {
00117    return (*this += -rhs);
00118 }
00119 
00120 
00121 // Scalar Mutator Operators
00122 // ------------------------
00123 template <unsigned N, typename T>
00124 inline       Point<N, T> &Point<N, T>::operator*=(const T &scale) {
00125    for(unsigned i = N; i--;)
00126       data[i] *= scale;
00127    
00128    return *this;
00129 }
00130 
00131 template <unsigned N, typename T>
00132 inline       Point<N, T> &Point<N, T>::operator/=(const T &scale) {
00133    if (NEQ(0, scale)) {
00134       for(unsigned i = N; i--;)
00135          data[i] /= scale;
00136    } else {
00137       cerr << "Error: Attempting to divide Point by zero" << endl << endl;
00138    }
00139    
00140    return *this;
00141 }
00142 
00143 
00144 // Arithmetic Operators
00145 // --------------------
00146 
00147 template <unsigned N, typename T>
00148 inline       Point<N, T>  Point<N, T>::operator+ (const Vector<N - 1, T> &rhs) const
00149 {
00150    T d[POINT_NO_ELEMENTS];
00151    
00152    d[N - 1] = data[N - 1];
00153    for(unsigned i = N - 1; i--;)
00154       d[i] = data[i] + rhs.data[i];
00155    
00156    return Point<N, T>(d);
00157 }
00158 
00159 template <unsigned N, typename T>
00160 inline       Point<N, T>  Point<N, T>::operator- (const Vector<N - 1, T> &rhs) const
00161 {
00162    T d[POINT_NO_ELEMENTS];
00163    
00164    d[N - 1] = data[N - 1];
00165    for(unsigned i = N - 1; i--;)
00166       d[i] = data[i] - rhs.data[i];
00167    
00168    return Point<N, T>(d);
00169 }
00170 
00171 template <unsigned N, typename T>
00172 inline       Vector<N - 1, T>  Point<N, T>::operator- (const Point<N, T> &rhs) const
00173 {
00174    T d[POINT_NO_ELEMENTS];
00175    
00176    for(unsigned i = N - 1; i--;)
00177       d[i] = data[i] - rhs.data[i];
00178    
00179    return Vector<N - 1, T>(d);
00180 }
00181 
00182 // Scalar Arithmetic Operators
00183 template <unsigned N, typename T>
00184 inline       Point<N, T>  Point<N, T>::operator* (const T &scale) const {
00185    T d[POINT_NO_ELEMENTS];
00186    
00187    for(unsigned i = N; i--;)
00188       d[i] = data[i] * scale;
00189    
00190    return Point<N, T>(d);
00191 }
00192 
00193 template <unsigned N, typename T>
00194 inline       Point<N, T>  Point<N, T>::operator/ (const T &scale) const {
00195    if (EQ(0, scale)) {
00196       cerr << "Error: Attempting to divide Point by zero" << endl << endl;
00197       
00198       return Point<N, T>();
00199    } else {
00200       T d[POINT_NO_ELEMENTS];
00201       
00202       for(unsigned i = N; i--;)
00203          d[i] = data[i] / scale;
00204       
00205       return Point<N, T>(d);
00206    }
00207 }
00208 
00209 
00210 // More Complex Functionality
00211 // --------------------------
00212 
00213 // @returns whether or not this Point is the zero point
00214 template <unsigned N, typename T>
00215 inline bool Point<N, T>::isZero() const {
00216    for(unsigned i = N; i--;) {
00217       if (data[i] != 0)
00218          return false;
00219    }
00220    
00221    return true;
00222 }
00223 
00224 // @returns the magnitude of the vector connecting this point to the one 
00225 //    passed in
00226 template <unsigned N, typename T>
00227 inline T Point<N, T>::getDistance(const Point<N, T> &v) const {
00228    return sqrt(getDistance2(v));
00229 }
00230 
00231 // @returns the squared magnitude of the point connecting this point to 
00232 //    the one passed in
00233 template <unsigned N, typename T>
00234 inline T Point<N, T>::getDistance2(const Point<N, T> &v) const {
00235    return (*this - v).getMagnitude2();
00236 }
00237 
00238 // @returns the sum of the components in this Point
00239 template <unsigned N, typename T>
00240 inline T Point<N, T>::getSum() const {
00241    T sum = 0;
00242    
00243    for(unsigned i = N; i--;)
00244       sum += data[i];
00245    
00246    return sum;
00247 }
00248 
00249 // @returns the average of the components in this Point
00250 template <unsigned N, typename T>
00251 inline T Point<N, T>::getAverage() const {
00252    return (getSum() / N);
00253 }
00254 
00255 
00256 // Specialized Point Functionality
00257 // --------------------------------
00258 
00259 // Convenience Constructor
00260 template <unsigned N, typename T>
00261 inline Point<N, T>::Point(const T &v0, const T &v1, const T &v2, 
00262                           const T &v3)
00263 {
00264    // Already filled in for you since this is a convenience constructor only
00265    
00266    if (N > 0)
00267       data[0] = v0;
00268    if (N > 1)
00269       data[1] = v1;
00270    if (N > 2)
00271       data[2] = v2;
00272    if (N > 3)
00273       data[3] = v3;
00274 }
00275 
00276 
00277 // Extra operators where Point is on right-hand side
00278 // --------------------------------------------------
00279 
00280 // @returns the N-length point resulting from multiplying a scalar by an 
00281 //    N-length point
00282 template <unsigned N, typename T>
00283 inline       Point<N, T>  operator* (const T &scale, 
00284                                      const Point<N, T> &rhs)
00285 {
00286    return rhs * scale;
00287 }
00288 
00289 // @returns (-1) * rhs, which is a negated version of the original right 
00290 //    hand side point
00291 template <unsigned N, typename T>
00292 inline       Point<N, T> operator- (const Point<N, T> &rhs)
00293 {
00294    return rhs * (-1);
00295 }
00296 
00297 // Prints a Point to an output stream
00298 template <unsigned N, typename T>
00299 inline       std::ostream      &operator<<(std::ostream &os, 
00300                                            const Point<N, T> &v)
00301 {
00302    os << "[ ";
00303    
00304    for(unsigned i = 0; i < N; ++i)
00305       os << v.data[i] << (i < N - 1 ? ", " : "");
00306 
00307    os << " ]";
00308    return os;
00309 }
00310 
00311 
00312 // Cleans up point (0's out entries that are less than epsilon)
00313 template <unsigned N, typename T>
00314 void Point<N, T>::cleanup() {
00315    for(unsigned i = N; i--;) {
00316       if (EQ(data[i], 0)) {
00317          data[i] = 0;
00318       }
00319    }
00320 }
00321 
00322 #endif // POINT_INL_
00323 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6