// 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. 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 { friend Point; // 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 centimeters for the internal unit, and adding // any specialized accessor functions for inches, miles, light-years, etc. double value[DIM]; // Centimeters public: // Constants (initialized in Cartesian.cpp) // --------- static DISTANCE ZERO; static DISTANCE ONE; // Constructors & accessors // ------------------------ Distance (); Distance (DOUBLE x); Distance (DOUBLE x, DOUBLE y); Distance (DOUBLE x, DOUBLE y, DOUBLE z); // The compiler will supply an acceptable copy constructor, destructor, and // assignment operator. 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 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" }; // The following functions should be moved to a separately compiled // implementation (.cpp) file: 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.value[ctr] = -value[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 DOUBLE ORIGIN; // Constant zero // Constructors & accessors // ------------------------ Point (); Point (DOUBLE x); Point (DOUBLE x, DOUBLE y); Point (DOUBLE x, DOUBLE y, DOUBLE 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" }; template inline Point& Point::operator+= (DISTANCE rs) {for (int ctr = 0; ctr < DIM; ++ctr) value[ctr] += rs.value[ctr]; return *this;} template inline Point& Point::operator-= (DISTANCE rs) {for (int ctr = 0; ctr < DIM; ++ctr) value[ctr] -= rs.value[ctr]; return *this;} // Logical operator // ---------------- template inline bool operator==(POINT ls, POINT rs) {for (int ctr = 0; ctr < DIM; ++ctr) if (ls.value[ctr] != rs.value[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 << ')'; } #endif