/* Project CADshell Design Automation Laboratory Dept. of Mechanical and Aerospace Engineering Arizona State University Copyright (C) 1998. All Rights Reserved. FILE: vmath.h MODULE: CADshell DEPENDS ON MODULE(S): none AUTHOR(S): Bernie Bettig OVERVIEW ======== Class definition for sh_Point, (== sh_Vector) sh_Transform. */ #ifndef __vmath_h #define __vmath_h #include #include class sh_Point; #define sh_Vector sh_Point // sh_Transform - transformation matrix class sh_Transform { public: enum sh_Trans {RotX, RotY, RotZ, Scale, ScaleX, ScaleY, ScaleZ, TranslateX, TranslateY, TranslateZ}; double mat[4][3]; sh_Transform(); sh_Transform(sh_Trans Trans, const double amount); sh_Transform(const sh_Transform &transMat); sh_Transform(sh_Point &zdir, sh_Point &xdir, sh_Point &translation); // zdir and xdir must be unit vectors void Concat(sh_Trans trans, const double val); void Translate(const double dx, const double dy, const double dz); void Translate(const sh_Point &d); sh_Transform operator *(const sh_Transform& transMat) const; sh_Transform& operator *=(const sh_Transform& transMat); sh_Point Transform(const sh_Point& point); sh_Point Rotate(const sh_Point& point); sh_Transform Inverse(); }; class sh_Point { public: double x, y, z; sh_Point() { x = y = z = 0.; } sh_Point(double _x, double _y, double _z) {x = _x; y = _y; z = _z;} sh_Point(double *pnt) {x = pnt[0]; y = pnt[1]; z = pnt[2];} Bool operator ==(const sh_Point& other) const; Bool operator !=(const sh_Point& other) const; sh_Point operator +(const sh_Point& point) const; sh_Point operator -(const sh_Point& point) const; sh_Point operator *(const double scalar) const; friend sh_Point operator *(const double& r, const sh_Point& p); sh_Point operator -() const {return sh_Point(-x, -y, -z);} sh_Point& operator +=(const sh_Point& point); sh_Point& operator -=(const sh_Point& point); sh_Point& operator *=(const double scalar); sh_Point& operator /=(const double scalar); operator double *() {return &(this->x);} void Transform(const sh_Transform& TransMat); void Rotate(const sh_Transform& TransMat); double Magnitude(); double Distance(const sh_Point& point); double Dot(const sh_Point& point); sh_Point Cross(const sh_Point& point); void UnitNormalize(); sh_Point UnitNormalized(); sh_Point Perpendicular(const sh_Point &reference); }; void StretchBounds(sh_Point& Min, sh_Point& Max, const sh_Point& point); inline void sh_Transform::Translate(const sh_Point &d) { mat[3][0] += d.x; mat[3][1] += d.y; mat[3][2] += d.z; } inline sh_Transform& sh_Transform::operator *=(const sh_Transform& T) { *this = *this * T; return *this; } inline Bool sh_Point::operator ==(const sh_Point& other) const { return other.x==x && other.y==y && other.z==z; } inline Bool sh_Point::operator !=(const sh_Point& other) const { return other.x!=x || other.y!=y || other.z!=z; } inline sh_Point sh_Point::operator +(const sh_Point& point) const { return sh_Point(x+point.x, y+point.y, z+point.z); } inline sh_Point sh_Point::operator -(const sh_Point& point) const { return sh_Point(x-point.x, y-point.y, z-point.z); } inline sh_Point sh_Point::operator *(const double scalar) const { return sh_Point(x*scalar, y*scalar, z*scalar); } inline sh_Point& sh_Point::operator +=(const sh_Point& point) { x += point.x; y += point.y; z += point.z; return *this; } inline sh_Point& sh_Point::operator -=(const sh_Point& point) { x -= point.x; y -= point.y; z -= point.z; return *this; } inline sh_Point& sh_Point::operator *=(const double scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; } inline sh_Point& sh_Point::operator /=(const double scalar) { if (scalar != 0. ) { x /= scalar; y /= scalar; z /= scalar; } else cout << "sh_Point: divide by zero error\n" << flush; return *this; } inline double sh_Point::Distance(const sh_Point &point) { return (*this - point).Magnitude(); } inline double sh_Point::Dot(const sh_Point &point) { return (x*point.x + y*point.y + z*point.z); } inline sh_Point sh_Point::Cross(const sh_Point &point) { return sh_Point(y*point.z-z*point.y, z*point.x-x*point.z, x*point.y-y*point.x); } inline void sh_Point::UnitNormalize() { double L = Magnitude(); if (L == 0.) { (*this) = sh_Point(0.,0.,0.); return; } else (*this) = (*this)*(1./L); } inline sh_Point sh_Point::UnitNormalized() { double L = Magnitude(); if (L == 0.) return sh_Point(0.,0.,0.); else return (*this)*(1./L); } inline void sh_Point::Transform(const sh_Transform& M) { sh_Point p; p.x = x*M.mat[0][0] + y*M.mat[1][0] + z*M.mat[2][0] + M.mat[3][0]; p.y = x*M.mat[0][1] + y*M.mat[1][1] + z*M.mat[2][1] + M.mat[3][1]; p.z = x*M.mat[0][2] + y*M.mat[1][2] + z*M.mat[2][2] + M.mat[3][2]; *this = p; } inline void sh_Point::Rotate(const sh_Transform& M) { sh_Point p; p.x = x*M.mat[0][0] + y*M.mat[1][0] + z*M.mat[2][0]; p.y = x*M.mat[0][1] + y*M.mat[1][1] + z*M.mat[2][1]; p.z = x*M.mat[0][2] + y*M.mat[1][2] + z*M.mat[2][2]; *this = p; } inline sh_Point sh_Transform::Transform(const sh_Point& r) { sh_Point p; p.x = r.x*mat[0][0] + r.y*mat[1][0] + r.z*mat[2][0] + mat[3][0]; p.y = r.x*mat[0][1] + r.y*mat[1][1] + r.z*mat[2][1] + mat[3][1]; p.z = r.x*mat[0][2] + r.y*mat[1][2] + r.z*mat[2][2] + mat[3][2]; return p; } inline sh_Point sh_Transform::Rotate(const sh_Point& r) { sh_Point p; p.x = r.x*mat[0][0] + r.y*mat[1][0] + r.z*mat[2][0]; p.y = r.x*mat[0][1] + r.y*mat[1][1] + r.z*mat[2][1]; p.z = r.x*mat[0][2] + r.y*mat[1][2] + r.z*mat[2][2]; return p; } // sh_Point_weighted : homogeneous coordinates class sh_Point_weighted : public sh_Point { public: double w; sh_Point_weighted() : sh_Point() { w = 0.; } sh_Point_weighted(double _x, double _y, double _z, double _w) : sh_Point(_x, _y, _z) {w = _w;} sh_Point_weighted(double *pnt) : sh_Point(pnt) {w = pnt[3];} }; #endif