00001
00002
00003
00004 #ifndef Point3DBase_Header
00005 #define Point3DBase_Header
00006
00007 #include <iostream>
00008 #include <math.h>
00009
00010 using namespace std;
00011
00012
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
00032
00033
00034
00035
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
00044
00045
00046
00047
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
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
00159 double Dot(const Point3DBase<T> &pt)
00160 {return (x*pt.x + y*pt.y + z*pt.z);}
00161
00162
00163
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
00174
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
00188 double Dist(Point3DBase<T> &pt) {
00189
00190 return( sqrt(SquaredDist(pt)) );
00191
00192 }
00193
00194
00195
00196
00197 double Angle(Point3DBase<T> &pt) {
00198
00199 double dotProduct = Dot(pt);
00200
00201 return acos(dotProduct);
00202
00203 }
00204
00205
00206
00207 void ForceMin(double min)
00208 { x = MAX(min, x); y = MAX(min, y); z = MAX(min, z); }
00209
00210
00211 void ForceMax(double max)
00212 { x = MAX(max, x); y = MAX(max, y); z = MAX(max, z); }
00213
00214
00215
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);
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);
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
00308 typedef Point3DBase<double> Point3D;
00309 typedef Point3DBase<int> iPoint3D;
00310
00311 #endif
00312