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
1.5.6