// Copyright (c) 1999 Philip A. Hardin (pahardin@cs.utexas.edu) // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License v2 or later. #ifndef PT3D_h #define PT3D_h #include #include "general.h" #include "pt2d.h" #include "ang3d.h" /*=========================================================================*/ struct pt3d : pt2d { enum {numDims=3}; private: typedef double xformMtrx[numDims+1][numDims+1]; public: coord z; pt3d() {}; pt3d(coord nx, coord ny, coord nz=0) : z(nz) {x=nx; y=ny;} pt3d(const coord* ptr) {x= *ptr++; y= *ptr++; z= *ptr++;} pt3d(coord*& ptr) {x= *ptr++; y= *ptr++; z= *ptr++;} pt3d(pt3d*& ptr) {*this= *ptr++;} // inline functions bool operator==(const pt3d& p) const {return (x==p.x and y==p.y and z==p.z);} bool operator!=(const pt3d& p) const {return (x!=p.x or y!=p.y or z!=p.z);} pt3d operator- () const {return pt3d(-x,-y,-z);} void operator+=(const pt3d& p) {x+=p.x; y+=p.y; z+=p.z;} void operator-=(const pt3d& p) {x-=p.x; y-=p.y; z-=p.z;} pt3d operator+ (const pt3d& p) const {return pt3d(x+p.x, y+p.y, z+p.z);} pt3d operator- (const pt3d& p) const {return pt3d(x-p.x, y-p.y, z-p.z);} void operator*=(coord sc) {x*=sc; y*=sc; z*=sc;} void operator*=(pt3d sc) {x*=sc.x; y*=sc.y; z*=sc.z;} pt3d operator* (coord s) const {return pt3d(x*s, y*s, z*s);} pt3d operator* (const pt3d& p) const {return pt3d(x*p.x, y*p.y, z*p.z);} coord Dot (const pt3d& p) const {return x*p.x +y*p.y +z*p.z;} void operator/=(coord dv) {x/=dv; y/=dv; z/=dv;} pt3d operator/ (coord dv) const {return pt3d(x/dv,y/dv,z/dv);} pt3d operator>>(ang2d) const; void operator>>=(ang2d a) {pt2d::operator>>=(a);} void operator>>=(double a) {pt2d::operator>>=(a);} void operator>>=(const ang3d& a) {*this= *this >> a;} void operator<<=(const ang3d& a) {*this= *this << a;} coord& operator[](int); coord operator[](int) const; coord Dist() const {return sqrt((double)(sqr(x)+sqr(y)+sqr(z)));} coord FastDist() const; pt2d Project() const {coord r=1/z; return pt2d(x*r,y*r);} ang3d Ang3d() const; void GetZCrossing(const pt3d&,coord); void GetZCrossing(const pt3d&,const pt3d&,coord); pt3d CrossProd(const pt3d&) const; void SetMax(const pt3d&); void SetMin(const pt3d&); bool IsBetween (const pt3d&,const pt3d&) const; bool IsBetweenInclusively(const pt3d&,const pt3d&) const; bool IsBetweenExclusively(const pt3d&,const pt3d&) const; // non-inline functions pt3d operator>> (const ang3d& a) const; // >> is Rotate pt3d operator<< (const ang3d& a) const; // << is Rotate Reverse pt3d operator>> (const double[3][3]) const; pt3d operator<< (const double[3][3]) const; pt3d operator>> (const xformMtrx) const; pt3d operator<< (const xformMtrx) const; pt3d operator>> (double a) const; // {pt3d p= *this; p.pt2d::operator>>=(a); return p;} void Interpolate(const pt3d& p1,const pt3d& p2,int i,int r); pt3d Normalized(coord=1) const; void Normalize(coord=1); void FastNormalize(coord=1); }; /*=========================================================================*/ inline pt3d::coord pt3d::FastDist() const { pt2d p2; p2.x= pt2d::FastDist(); p2.y= z; return p2.FastDist(); } /*-------------------------------------------------------------------------*/ inline pt3d::coord& pt3d::operator[](int i) { if (i==0) return x; else if (i==1) return y; else return z; } inline pt3d::coord pt3d::operator[](int i) const { if (i==0) return x; else if (i==1) return y; else return z; } /*-------------------------------------------------------------------------*/ inline ang3d pt3d::Ang3d() const { ang3d ang; pt2d pt2; ang.xy= pt2d::Ang2d(); pt2.x= pt2d::Dist(); pt2.y= z; ang.xz= pt2.Ang2d(); ang.yz= 0; return ang; } /*-------------------------------------------------------------------------*/ inline pt3d pt3d::operator>>(ang2d ang) const { double sinAng= sinTbl[ang & (2*MA_PI-1)]; double cosAng= cosTbl[ang & (2*MA_PI-1)]; return pt3d((coord)(cosAng*x - sinAng*y),(coord)(cosAng*y + sinAng*x),z); } /*-------------------------------------------------------------------------*/ // Computes the intersection of the plane z=planez and the infinite line // from this point thru endPt. Stores the intersection in *this point. inline void pt3d::GetZCrossing(const pt3d& endPt, coord planez) { coord temp= (planez -z)/(endPt.z -z); // assumes denominator is nonzero! x += temp * (endPt.x -x); y += temp * (endPt.y -y); z= planez; } /*-------------------------------------------------------------------------*/ // Computes the intersection of the plane z=planez and the infinite line // from beginPt thru endPt. Stores the intersection in *this point. inline void pt3d::GetZCrossing(const pt3d& beginPt, const pt3d& endPt, coord planez) { coord temp= (planez -beginPt.z)/(endPt.z -beginPt.z); x= beginPt.x + temp * (endPt.x -beginPt.x); y= beginPt.y + temp * (endPt.y -beginPt.y); z= planez; } /*-------------------------------------------------------------------------*/ inline pt3d pt3d::CrossProd(const pt3d& p) const { return pt3d( y*p.z - z*p.y, -(x*p.z - z*p.x), x*p.y - y*p.x ); } /*-------------------------------------------------------------------------*/ inline void pt3d::SetMax(const pt3d& pt) { if (pt.x >x) x= pt.x; if (pt.y >y) y= pt.y; if (pt.z >z) z= pt.z; } /*-------------------------------------------------------------------------*/ inline void pt3d::SetMin(const pt3d& pt) { if (pt.x > (istream& in, pt3d& p) { return in >> p.x >> p.y >> p.z; } #endif