// Cartesian points and Distances classes // -------------------------------------- #ifndef POINT #define POINT const Point #define DISTANCE const Distance #include // These class templates support linear, plane, or spatial distances // and Cartesian points. (In this demonstration version, some functions // that should be compiled separately in Cartesian.cpp are coded inline // in order to avoid compiler-dependent template restrictions. template class Point; // (1). Distance (extent) class template // -------------------------------- template // 1, 2, or 3 (Higher dimensionality may work // in some contexts, but has not been validated) class Distance { // The unit of measure is left unspecified, so that the class can be used // for both abstract mathematics and real-world applications. In a physical // application, we recommend standardizing on centimeters for the internal // unit, and then adding any needed specialized accessor functions for inches, // miles, kilometers, angstroms, light-years, etc. double value[DIM]; public: // Constants (initialized in Cartesian.cpp) // --------- static DISTANCE ZERO; static DISTANCE ONE; // Constructors & accessors // ------------------------ Distance (DOUBLE x=0, DOUBLE y=0, DOUBLE z=0) {value[0] = x; if (DIM > 1) value[1] = y; if (DIM > 2) value[2] = z; } // The compiler will supply an acceptable copy constructor, destructor, and // assignment operator. double& operator() (UINT coord) // General {assert(coord < DIM); return value[coord];} // accessor double operator() (UINT coord) const {assert(coord < DIM); return value[coord];} double x() const {return (*this)(0);} // Conventional double y() const {return (*this)(1);} // named double z() const {return (*this)(2);} // accessors double magnitude() const {double result = value[0] * value[0]; for (int ctr = 1; ctr < DIM; ++ctr) result += value[ctr] * value[ctr]; return sqrt(result); } // Arithmetic operators // -------------------- #define Class Distance< DIM > #include "additive.hpp" }; // These template function implementations should be moved to Cartesian.cpp template inline Distance& Distance::operator+= (DISTANCE rs) {for (int ctr = 0; ctr < DIM; ++ctr) value[ctr] += rs.value[ctr]; return *this;} template inline Distance& Distance::operator-= (DISTANCE rs) {for (int ctr = 0; ctr < DIM; ++ctr) value[ctr] -= rs.value[ctr]; return *this;} template inline Distance& Distance::operator*= (DOUBLE rs) {for (int ctr = 0; ctr < DIM; ++ctr) value[ctr] *= rs; return *this;} template inline Distance& Distance::operator/= (DOUBLE rs) {for (int ctr = 0; ctr < DIM; ++ctr) value[ctr] /= rs; return *this;} template inline Distance Distance::operator-() const {Distance result; for (int ctr = 0; ctr < DIM; ++ctr) result(ctr) = -(*this)(ctr); return result;} // Logical operator // ---------------- template inline bool operator==(DISTANCE ls, DISTANCE rs) {for (int ctr = 0; ctr < DIM; ++ctr) if (ls(ctr) != rs(ctr)) return false; return true; } template ostream& operator<< (ostream& ls, DISTANCE rs) {ls << '(' << rs(0); for (int ctr = 1; ctr < DIM; ++ctr) ls << ',' << rs(ctr); return ls << ')'; } // (2). Point class // ----------------- #define POINT const Point template class Point { double value[DIM]; public: static POINT ORIGIN; // Constant zero initialized in Cartesian.cpp // Constructors & accessors // ------------------------ Point (DOUBLE x=0, DOUBLE y=0, DOUBLE z=0) {value[0] = x; if (DIM > 1) value[1] = y; if (DIM > 2) value[2] = z; } double operator() (UINT coord) const // General {assert(coord < DIM); return value[coord];} // accessor double x() const {return (*this)(0);} // Conventional double y() const {return (*this)(1);} // named double z() const {return (*this)(2);} // accessors #define PointClass Point #include "PointExt.hpp" Distance operator- (POINT rs) {Distance result; for (int ctr = 0; ctr < DIM; ++ctr) result(ctr) = (*this)(ctr) - rs(ctr); return result; } }; template inline Point& Point::operator+= (DISTANCE rs) {for (int ctr = 0; ctr < DIM; ++ctr) value[ctr] += rs(ctr); return *this;} template inline Point& Point::operator-= (DISTANCE rs) {for (int ctr = 0; ctr < DIM; ++ctr) value[ctr] -= rs(ctr); return *this;} // Logical operator // ---------------- template inline bool operator==(POINT ls, POINT rs) {for (int ctr = 0; ctr < DIM; ++ctr) if (ls(ctr) != rs.(ctr)) return false; return true; } template ostream& operator<< (ostream& ls, POINT rs) {ls << '(' << rs(0); for (int ctr = 1; ctr < DIM; ++ctr) ls << ',' << rs(ctr); return ls << ')'; } #undef Class #endif