/Users/craigcornelius/Projects/SPRING Mac Release 0.2/point3d.h

Go to the documentation of this file.
00001 // $Id: point3d.h,v 1.33 2006/05/24 16:52:41 sean Exp $
00002 // $Copyright: (c)2001 National Biocomputation Center, Stanford University $
00003 
00004 #ifndef Point3DBase_Header
00005 #define Point3DBase_Header
00006 
00007 #include <iostream>
00008 #include <math.h>
00009 
00010 using namespace std;
00011 
00012 //using namespace std;
00013 
00014 template <class T> class Point3DBase {
00015     
00016     
00017 public:
00018     
00019     T x,y,z;
00020     Point3DBase() {x = y = z = 0;}
00021     Point3DBase(T xin, T yin, T zin) {
00022         x = xin; y = yin; z = zin; }
00023     Point3DBase(const Point3DBase<T> &pt) { 
00024         x = pt.x; y = pt.y; z = pt.z; }
00025     
00026     friend Point3DBase<T> operator+(const Point3DBase<T> &pt1, 
00027         const Point3DBase<T> &pt2) { 
00028         return (Point3DBase(pt1.x + pt2.x, pt1.y + pt2.y, pt1.z + pt2.z)); }
00029     
00030         /*
00031         friend Point3DBase<T> operator+(const Point3DBase<T> &pt, const int i) {
00032         return (Point3DBase<T>(pt.x + i, pt.y + i, pt.z + i)); }
00033         
00034           friend Point3DBase<T> operator+(const int i, const Point3DBase<T> &pt) {
00035           return (Point3DBase<T>(pt.x + i, pt.y + i, pt.z + i)); }
00036     */
00037     
00038     friend Point3DBase<T> operator-(const Point3DBase<T> &pt1, 
00039         const Point3DBase<T> &pt2) {
00040         return (Point3DBase<T>(pt1.x - pt2.x, pt1.y - pt2.y, pt1.z - pt2.z)); }
00041     
00042         /*
00043         friend Point3DBase<T> operator-(const Point3DBase<T> &pt, const int i) {
00044         return (Point3DBase<T>(pt.x - i, pt.y - i, pt.z - i)); }
00045         
00046           friend Point3DBase<T> operator-(const int i, const Point3DBase<T> &pt) {
00047           return (Point3DBase<T>(pt.x - i, pt.y - i, pt.z - i)); }
00048     */
00049     
00050     friend Point3DBase<T> operator-(const Point3DBase<T> &pt) {
00051         return (Point3DBase<T>(-pt.x, -pt.y, -pt.z)); }
00052     
00053     friend Point3DBase<T> operator*(const Point3DBase<T> &pt, const int i) {
00054         return (Point3DBase<T>(pt.x * i, pt.y * i, pt.z * i)); }
00055     
00056     friend Point3DBase<T> operator*(const int i, const Point3DBase<T> &pt) {
00057         return (Point3DBase<T>(pt.x * i, pt.y * i, pt.z * i)); }
00058     
00059     friend Point3DBase<T> operator*(const Point3DBase<T> &pt, const double d) {
00060         return (Point3DBase<T>((T)(pt.x * d), (T)(pt.y * d), (T)(pt.z * d))); }
00061     
00062     friend Point3DBase<T> operator*(const double d, const Point3DBase<T> &pt) {
00063         return (Point3DBase<T>((T)(pt.x * d), (T)(pt.y * d), (T)(pt.z * d))); }
00064     
00065     friend Point3DBase<T> operator*(const Point3DBase<T> &pt1, 
00066         const Point3DBase<T> &pt2) {
00067         return (Point3DBase<T>((T)(pt1.x * pt2.x), 
00068             (T)(pt1.y * pt2.y), 
00069             (T)(pt1.z * pt2.z))); }
00070     
00071     friend Point3DBase<T> operator/(const Point3DBase<T> &pt, const int i) {
00072         return (Point3DBase<T>(pt.x/i, pt.y/i, pt.z/i)); }
00073     
00074     friend Point3DBase<T> operator/(const Point3DBase<T> &pt, const double d) {
00075         return (Point3DBase<T>((T)(pt.x/d), (T)(pt.y/d), (T)(pt.z/d))); }
00076     
00077     friend Point3DBase<T> operator/(const Point3DBase<T> &pt1, 
00078         const Point3DBase<T> &pt2) {
00079         return (Point3DBase<T>((T)(pt1.x/pt2.x), 
00080             (T)(pt1.y/pt2.y), 
00081             (T)(pt1.z/pt2.z))); }
00082     
00083     friend ostream& operator<<(ostream &os, const Point3DBase<T> &pt) {
00084         return (os << pt.x << "," << pt.y << "," << pt.z); }
00085     
00086     friend istream& operator>>(istream &is, Point3DBase<T> &pt) {
00087         is >> pt.x; is.ignore(); is >> pt.y; is.ignore(); is >> pt.z;
00088         return(is); }
00089     
00090     Point3DBase<T> operator=(const Point3DBase<T> &pt) 
00091     { x = pt.x; y = pt.y; z = pt.z; return(*this); }
00092     
00093     Point3DBase<T> operator-=(const Point3DBase<T> &pt) 
00094     { x -= pt.x; y -= pt.y; z -= pt.z; return(*this); }
00095     
00096     Point3DBase<T> operator+=(const Point3DBase<T> &pt) 
00097     { x += pt.x; y += pt.y; z += pt.z; return(*this); }
00098     
00099     Point3DBase<T> operator*=(const int i) 
00100     { x *= i; y *= i; z *= i; return(*this); }
00101     
00102     Point3DBase<T> operator*=(const double d) 
00103     { x = (T)(double(x)*d); y = (T)(double(y)*d); z = (T)(double(z)*d); 
00104     return(*this); }
00105     
00106     Point3DBase<T> operator*=(const Point3DBase<T> &pt) 
00107     { x *= pt.x; y *= pt.y; z *= pt.z; return(*this); }
00108     
00109     Point3DBase<T> operator/=(const int i) 
00110     { x /= i; y /= i; z /= i; return(*this); }
00111     
00112     Point3DBase<T> operator/=(const double d) 
00113     { x = (T)(double(x)/d); y = (T)(double(y)/d); z = (T)(double(z)/d);
00114     return(*this); }
00115     
00116     Point3DBase<T> operator/=(const Point3DBase<T> &pt) 
00117     { x /= pt.x; y /= pt.y; z /= pt.z; return(*this); }
00118     
00119     friend int operator==(const Point3DBase<T> &pt1, const Point3DBase<T> &pt2) 
00120     { return((pt1.x == pt2.x) && (pt1.y == pt2.y) && (pt1.z == pt2.z)); }
00121     
00122     friend int operator!=(const Point3DBase<T> &pt1, const Point3DBase<T> &pt2) 
00123     { return((pt1.x != pt2.x) || (pt1.y != pt2.y) || (pt1.z != pt2.z)); }
00124     
00125     friend int operator<(const Point3DBase<T> &pt1, const Point3DBase<T> &pt2) 
00126     { return ((pt1.x < pt2.x) && (pt1.y < pt2.y) && (pt1.z < pt2.z)); }
00127     
00128     friend int operator>(const Point3DBase<T> &pt1, const Point3DBase<T> &pt2) 
00129     { return ((pt1.x > pt2.x) && (pt1.y > pt2.y) && (pt1.z > pt2.z)); }
00130     
00131     double Squared()
00132     { return (x*x + y*y + z*z); }
00133     
00134     double Length()
00135     { return (sqrt(x*x + y*y + z*z)); }
00136     
00137     Point3DBase<T> Abs()
00138     { return (Point3DBase<T>( fabs(x), fabs(y), fabs(z) )); }
00139     
00140     int IsZero()
00141     { return ( (x==0.0) && (y==0.0) && (z==0.0) ); }
00142     
00143     void Normalize()
00144     { 
00145         double len = Length();
00146         if (len == 0.0) {
00147             //printf("point3d.h::Normalize div by 0, set to 1,0,0 for now\n");
00148             x = T(1); y = T(0); z = T(0);
00149             return;
00150         }
00151         x = T(x/len); y = T(y/len); z = T(z/len);
00152     }
00153     
00154     Point3DBase<T> Sign()
00155     { return( Point3DBase<T>((x >= 0), (y >= 0), (z >= 0)) ); }
00156     
00157 
00158         // returns the dot-product of two vectors
00159     double Dot(const Point3DBase<T> &pt)
00160     {return (x*pt.x + y*pt.y + z*pt.z);}
00161     
00162 
00163         // returns the cross-product of two vectors
00164     Point3DBase<T> Cross(const Point3DBase<T> &pt)
00165     {return (Point3DBase<T>((T)(y*pt.z - z*pt.y), 
00166     (T)(z*pt.x - x*pt.z), 
00167     (T)(x*pt.y - y*pt.x))); }
00168     
00169     double Determinant(const Point3DBase<T> &pt1, const Point3DBase<T> &pt2)
00170     {return (x*(pt1.y*pt2.z - pt1.z*pt2.y) - y*(pt1.x*pt2.z - pt1.z*pt2.x) +
00171     z*(pt1.x*pt2.y - pt1.y*pt2.x)); }
00172     
00173     // BE AWARE OF OVER/UNDERFLOW!  
00174     // (Type should probably be double to prevent over/underflow on the subtract)
00175     double SquaredDist(Point3DBase<T> &pt) { 
00176         Point3DBase<T> diff = *this - pt;
00177         return (diff.Squared());
00178     }
00179     
00180     void interp(Point3DBase<T> u, Point3DBase<T> v, double lambda) {            
00181         x = u.x + lambda * (v.x - u.x);
00182         y = u.y + lambda * (v.y - u.y);
00183         z = u.z + lambda * (v.z - u.z);
00184     }
00185     
00186 
00187         // returns the distance
00188     double Dist(Point3DBase<T> &pt) { 
00189 
00190                 return( sqrt(SquaredDist(pt)) );
00191 
00192         }
00193     
00194 
00195         // returns the angle in the range [0, PI] between this and the input vector
00196 
00197         double Angle(Point3DBase<T> &pt) {
00198 
00199                 double dotProduct = Dot(pt);
00200 
00201                 return acos(dotProduct);
00202 
00203         }
00204 
00205 
00206     // bounds values by min
00207     void ForceMin(double min) 
00208     { x = MAX(min, x); y = MAX(min, y); z = MAX(min, z); }
00209     
00210     // bounds values by max
00211     void ForceMax(double max) 
00212     { x = MAX(max, x); y = MAX(max, y); z = MAX(max, z); }
00213     
00214 
00215         // rotates a point given the inputted rotation matrix
00216     void Xform(double M[4][4]) {
00217         Point3DBase<T> newpos;
00218         newpos.x = x*M[0][0] + y*M[1][0] + z*M[2][0];
00219         newpos.y = x*M[0][1] + y*M[1][1] + z*M[2][1];
00220         newpos.z = x*M[0][2] + y*M[1][2] + z*M[2][2];
00221         x = newpos.x; y = newpos.y; z = newpos.z;
00222     }
00223                 int insideQuadrilateral(const Point3DBase<T> p0,const Point3DBase<T> p1, 
00224                                                                                                 const Point3DBase<T> p2,const Point3DBase<T> p3) 
00225 {
00226 #define EPSILON  0.00001
00227 #define TWOPI 6.283185307179586476925287
00228 
00229         Point3DBase<T> verts[4];
00230         verts[0] = p0;
00231         verts[1] = p1;
00232         verts[2] = p2;
00233         verts[3] = p3; 
00234         
00235         Point3DBase<T> p4,p5;
00236   
00237   double m1,m2;
00238   double anglesum=0,costheta;
00239 
00240         for (int i=0;i<4;i++) {
00241 
00242         p4.x = verts[i].x - x;
00243         p4.y = verts[i].y - y;
00244         p4.z = verts[i].z - z;
00245         p5.x = verts[(i+1)%4].x - x;
00246         p5.y = verts[(i+1)%4].y - y;
00247         p5.z = verts[(i+1)%4].z - z;
00248 
00249         m1 = p4.Length();
00250         m2 = p5.Length();
00251         if (m1*m2 <= EPSILON)
00252          return(1); /* We are on a node, consider this inside */
00253         else
00254          costheta = (p4.x*p5.x + p4.y*p5.y + p4.z*p5.z) / (m1*m2);
00255 
00256         anglesum += acos(costheta);
00257         }
00258         
00259         double diff = anglesum - TWOPI;
00260         if (sqrt(diff*diff) <= EPSILON) return (1);
00261         return (0);
00262 }
00263 
00264 int insideTriangle(const Point3DBase<T> p0, const Point3DBase<T> p1,
00265                                                                          const Point3DBase<T> p2) 
00266 {
00267 #define EPSILON  0.00001
00268 #define TWOPI 6.283185307179586476925287
00269 
00270         Point3DBase<T> verts[3];
00271         verts[0] = p0;
00272         verts[1] = p1;
00273         verts[2] = p2; 
00274         
00275         Point3DBase<T> p4,p5;
00276   
00277   double m1,m2;
00278   double anglesum=0.0;
00279         double costheta;
00280 
00281         for (int i=0;i<3;i++) {
00282 
00283         p4.x = verts[i].x - x;
00284         p4.y = verts[i].y - y;
00285         p4.z = verts[i].z - z;
00286         p5.x = verts[(i+1)%3].x - x;
00287         p5.y = verts[(i+1)%3].y - y;
00288         p5.z = verts[(i+1)%3].z - z;
00289 
00290         m1 = p4.Length();
00291         m2 = p5.Length();
00292         if (m1*m2 <= EPSILON)
00293          return(1); /* We are on a node, consider this inside */
00294         else
00295          costheta = (p4.x*p5.x + p4.y*p5.y + p4.z*p5.z) / (m1*m2);
00296 
00297         anglesum += acos(costheta);
00298         }
00299         double diff = anglesum - TWOPI;
00300         if (sqrt(diff*diff) <= EPSILON) return (1);
00301         return (0);
00302 }
00303     
00304 };
00305 
00306 
00307 // instantiations
00308 typedef Point3DBase<double>     Point3D;
00309 typedef Point3DBase<int>        iPoint3D;
00310 
00311 #endif
00312 

Generated on Thu Aug 30 11:03:15 2007 for SPRING Mac by  doxygen 1.5.3