csgeom/math3d_d.h
Go to the documentation of this file.00001 /* 00002 Copyright (C) 1998,1999,2000 by Jorrit Tyberghein 00003 Largely rewritten by Ivan Avramovic <ivan@avramovic.com> 00004 Converted to double by Thomas Hieber 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public 00017 License along with this library; if not, write to the Free 00018 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 */ 00020 00021 #ifndef __CS_MATH3D_D_H__ 00022 #define __CS_MATH3D_D_H__ 00023 00024 #include "cstypes.h" 00025 00032 #ifndef ABS 00033 #define ABS(x) ((x)<0?-(x):(x)) 00034 #endif 00035 00036 class csDVector3; 00037 class csDMatrix3; 00038 class csVector3; 00039 00040 inline double dSqr (double d) 00041 { 00042 return d * d; 00043 } 00044 00048 class csDVector3 00049 { 00050 public: 00052 double x; 00054 double y; 00056 double z; 00057 00063 csDVector3 () {} 00064 00070 csDVector3 (double m) : x(m), y(m), z(m) {} 00071 00073 csDVector3 (double ix, double iy, double iz = 0) { x = ix; y = iy; z = iz; } 00074 00076 csDVector3 (const csDVector3& v) { x = v.x; y = v.y; z = v.z; } 00077 00079 csDVector3 (const csVector3&); 00080 00082 inline friend 00083 csDVector3 operator+ (const csDVector3& v1, const csDVector3& v2) 00084 { return csDVector3(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); } 00085 00087 inline friend 00088 csDVector3 operator- (const csDVector3& v1, const csDVector3& v2) 00089 { return csDVector3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); } 00090 00092 inline friend double operator* (const csDVector3& v1, const csDVector3& v2) 00093 { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; } 00094 00096 inline friend 00097 csDVector3 operator% (const csDVector3& v1, const csDVector3& v2) 00098 { 00099 return csDVector3 (v1.y*v2.z-v1.z*v2.y, 00100 v1.z*v2.x-v1.x*v2.z, 00101 v1.x*v2.y-v1.y*v2.x); 00102 } 00103 00105 void Cross (const csDVector3 & px, const csDVector3 & py) 00106 { 00107 x = px.y*py.z - px.z*py.y; 00108 y = px.z*py.x - px.x*py.z; 00109 z = px.x*py.y - px.y*py.x; 00110 } 00111 00113 inline friend csDVector3 operator* (const csDVector3& v, double f) 00114 { return csDVector3(v.x*f, v.y*f, v.z*f); } 00115 00117 inline friend csDVector3 operator* (double f, const csDVector3& v) 00118 { return csDVector3(v.x*f, v.y*f, v.z*f); } 00119 00121 inline friend csDVector3 operator/ (const csDVector3& v, double f) 00122 { f = 1.0f/f; return csDVector3(v.x*f, v.y*f, v.z*f); } 00123 00125 inline friend bool operator== (const csDVector3& v1, const csDVector3& v2) 00126 { return v1.x==v2.x && v1.y==v2.y && v1.z==v2.z; } 00127 00129 inline friend bool operator!= (const csDVector3& v1, const csDVector3& v2) 00130 { return v1.x!=v2.x || v1.y!=v2.y || v1.z!=v2.z; } 00131 00133 inline friend 00134 csDVector3 operator>> (const csDVector3& v1, const csDVector3& v2) 00135 { return v2*(v1*v2)/(v2*v2); } 00136 00138 inline friend 00139 csDVector3 operator<< (const csDVector3& v1, const csDVector3& v2) 00140 { return v1*(v1*v2)/(v1*v1); } 00141 00143 inline friend bool operator< (const csDVector3& v, double f) 00144 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f; } 00145 00147 inline friend bool operator> (double f, const csDVector3& v) 00148 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f; } 00149 00151 inline double operator[](int n) const {return !n?x:n&1?y:z;} 00152 00154 inline double & operator[](int n){return !n?x:n&1?y:z;} 00155 00157 inline csDVector3& operator+= (const csDVector3& v) 00158 { 00159 x += v.x; 00160 y += v.y; 00161 z += v.z; 00162 00163 return *this; 00164 } 00165 00167 inline csDVector3& operator-= (const csDVector3& v) 00168 { 00169 x -= v.x; 00170 y -= v.y; 00171 z -= v.z; 00172 00173 return *this; 00174 } 00175 00177 inline csDVector3& operator*= (double f) 00178 { x *= f; y *= f; z *= f; return *this; } 00179 00181 inline csDVector3& operator/= (double f) 00182 { x /= f; y /= f; z /= f; return *this; } 00183 00185 inline csDVector3 operator+ () const { return *this; } 00186 00188 inline csDVector3 operator- () const { return csDVector3(-x,-y,-z); } 00189 00191 inline void Set (double sx, double sy, double sz) { x = sx; y = sy; z = sz; } 00192 00194 double Norm () const; 00195 00197 double SquaredNorm () const; 00198 00204 csDVector3 Unit () const { return (*this)/(this->Norm()); } 00205 00207 inline static double Norm (const csDVector3& v) { return v.Norm(); } 00208 00210 inline static csDVector3 Unit (const csDVector3& v) { return v.Unit(); } 00211 00213 void Normalize(); 00214 }; 00215 00216 00220 class csDMatrix3 00221 { 00222 public: 00223 double m11, m12, m13; 00224 double m21, m22, m23; 00225 double m31, m32, m33; 00226 00227 public: 00229 csDMatrix3 (); 00230 00232 csDMatrix3 (double m11, double m12, double m13, 00233 double m21, double m22, double m23, 00234 double m31, double m32, double m33); 00235 00237 inline csDVector3 Row1() const { return csDVector3 (m11,m12,m13); } 00238 00240 inline csDVector3 Row2() const { return csDVector3 (m21,m22,m23); } 00241 00243 inline csDVector3 Row3() const { return csDVector3 (m31,m32,m33); } 00244 00246 inline csDVector3 Col1() const { return csDVector3 (m11,m21,m31); } 00247 00249 inline csDVector3 Col2() const { return csDVector3 (m12,m22,m32); } 00250 00252 inline csDVector3 Col3() const { return csDVector3 (m13,m23,m33); } 00253 00255 inline void Set (double m11, double m12, double m13, 00256 double m21, double m22, double m23, 00257 double m31, double m32, double m33) 00258 { 00259 csDMatrix3::m11 = m11; csDMatrix3::m12 = m12; csDMatrix3::m13 = m13; 00260 csDMatrix3::m21 = m21; csDMatrix3::m22 = m22; csDMatrix3::m23 = m23; 00261 csDMatrix3::m31 = m31; csDMatrix3::m32 = m32; csDMatrix3::m33 = m33; 00262 } 00263 00265 csDMatrix3& operator+= (const csDMatrix3& m); 00266 00268 csDMatrix3& operator-= (const csDMatrix3& m); 00269 00271 csDMatrix3& operator*= (const csDMatrix3& m); 00272 00274 csDMatrix3& operator*= (double s); 00275 00277 csDMatrix3& operator/= (double s); 00278 00280 inline csDMatrix3 operator+ () const { return *this; } 00282 inline csDMatrix3 operator- () const 00283 { 00284 return csDMatrix3(-m11,-m12,-m13, 00285 -m21,-m22,-m23, 00286 -m31,-m32,-m33); 00287 } 00288 00290 void Transpose (); 00291 00293 csDMatrix3 GetTranspose () const; 00294 00296 inline csDMatrix3 GetInverse () const 00297 { 00298 csDMatrix3 C( 00299 (m22*m33 - m23*m32), -(m12*m33 - m13*m32), (m12*m23 - m13*m22), 00300 -(m21*m33 - m23*m31), (m11*m33 - m13*m31), -(m11*m23 - m13*m21), 00301 (m21*m32 - m22*m31), -(m11*m32 - m12*m31), (m11*m22 - m12*m21) ); 00302 double s = (double)1./(m11*C.m11 + m12*C.m21 + m13*C.m31); 00303 00304 C *= s; 00305 00306 return C; 00307 } 00308 00310 void Invert() { *this = GetInverse (); } 00311 00313 double Determinant () const; 00314 00316 void Identity (); 00317 00319 friend csDMatrix3 operator+ (const csDMatrix3& m1, const csDMatrix3& m2); 00321 friend csDMatrix3 operator- (const csDMatrix3& m1, const csDMatrix3& m2); 00323 friend csDMatrix3 operator* (const csDMatrix3& m1, const csDMatrix3& m2); 00324 00326 inline friend csDVector3 operator* (const csDMatrix3& m, const csDVector3& v) 00327 { 00328 return csDVector3 (m.m11*v.x + m.m12*v.y + m.m13*v.z, 00329 m.m21*v.x + m.m22*v.y + m.m23*v.z, 00330 m.m31*v.x + m.m32*v.y + m.m33*v.z); 00331 } 00332 00334 friend csDMatrix3 operator* (const csDMatrix3& m, double f); 00336 friend csDMatrix3 operator* (double f, const csDMatrix3& m); 00338 friend csDMatrix3 operator/ (const csDMatrix3& m, double f); 00340 friend bool operator== (const csDMatrix3& m1, const csDMatrix3& m2); 00342 friend bool operator!= (const csDMatrix3& m1, const csDMatrix3& m2); 00344 friend bool operator< (const csDMatrix3& m, double f); 00346 friend bool operator> (double f, const csDMatrix3& m); 00347 }; 00348 00349 00355 class csDPlane 00356 { 00357 public: 00359 csDVector3 norm; 00360 00362 double DD; 00363 00365 csDPlane () : norm(0,0,1), DD(0) {} 00366 00368 csDPlane (const csDVector3& plane_norm, double d=0) : 00369 norm(plane_norm), DD(d) {} 00370 00372 csDPlane (double a, double b, double c, double d=0) : norm(a,b,c), DD(d) {} 00373 00375 inline csDVector3& Normal () { return norm; } 00377 inline const csDVector3& Normal () const { return norm; } 00378 00380 inline double A () const { return norm.x; } 00382 inline double B () const { return norm.y; } 00384 inline double C () const { return norm.z; } 00386 inline double D () const { return DD; } 00387 00389 inline double& A () { return norm.x; } 00391 inline double& B () { return norm.y; } 00393 inline double& C () { return norm.z; } 00395 inline double& D () { return DD; } 00396 00398 inline void Set (double a, double b, double c, double d) 00399 { norm.x = a; norm.y = b; norm.z = c; DD = d; } 00400 00402 inline double Classify (const csDVector3& pt) const { return norm*pt+DD; } 00403 00405 static double Classify (double A, double B, double C, double D, 00406 const csDVector3& pt) 00407 { return A*pt.x + B*pt.y + C*pt.z + D; } 00408 00414 inline double Distance (const csDVector3& pt) const 00415 { return ABS (Classify (pt)); } 00416 00418 void Invert () { norm = -norm; DD = -DD; } 00419 00421 void Normalize () 00422 { 00423 double f = norm.Norm (); 00424 if (f) { norm /= f; DD /= f; } 00425 } 00426 00427 }; 00428 00433 class csDMath3 00434 { 00435 public: 00443 static int WhichSide3D (const csDVector3& p, 00444 const csDVector3& v1, const csDVector3& v2) 00445 { 00446 // double s = p * (v1%v2); (original expression: expanded to the below:) 00447 double s = p.x*(v1.y*v2.z-v1.z*v2.y) + p.y*(v1.z*v2.x-v1.x*v2.z) + 00448 p.z*(v1.x*v2.y-v1.y*v2.x); 00449 if (s < 0) return 1; 00450 else if (s > 0) return -1; 00451 else return 0; 00452 } 00453 00459 static bool Visible (const csDVector3& p, const csDVector3& t1, 00460 const csDVector3& t2, const csDVector3& t3); 00461 00467 static bool Visible (const csDVector3& p, const csDPlane& pl) 00468 { return pl.Classify (p) <= 0; } 00469 00479 static void Between (const csDVector3& v1, const csDVector3& v2, 00480 csDVector3& v, double pct, double wid); 00481 00488 static void SetMinMax (const csDVector3& v, 00489 csDVector3& min, csDVector3& max) 00490 { 00491 if (v.x > max.x) max.x = v.x; else if (v.x < min.x ) min.x = v.x; 00492 if (v.y > max.y) max.y = v.y; else if (v.y < min.y ) min.y = v.y; 00493 if (v.z > max.z) max.z = v.z; else if (v.z < min.z ) min.z = v.z; 00494 } 00495 00501 inline static double Area3 (const csDVector3 &a, const csDVector3 &b, 00502 const csDVector3 &c) 00503 { 00504 csDVector3 v1 = b - a; 00505 csDVector3 v2 = c - a; 00506 return ((v1.y * v2.z + v1.z * v2.x + v1.x * v2.y) - 00507 (v1.y * v2.x + v1.x * v2.z + v1.z * v2.y)); 00508 } 00509 00515 inline static void CalcNormal (csDVector3& norm, const csDVector3& v1, 00516 const csDVector3& v2, const csDVector3& v3) 00517 { 00518 norm = (v1-v2)%(v1-v3); 00519 } 00520 00526 static void CalcNormal (csDVector3& norm, 00527 const csDVector3& v, const csDVector3& u) 00528 { norm = u%v; /* NOT v%u - vertexes are defined clockwise */ } 00529 00536 static void CalcPlane (const csDVector3& v1, const csDVector3& v2, 00537 const csDVector3& v3, csDVector3& normal, double& D) 00538 { 00539 normal = (v1-v2)%(v1-v3); 00540 D = - (normal * v1); 00541 } 00542 00549 static bool PlanesEqual (const csDPlane& p1, const csDPlane& p2) 00550 { 00551 return ( ( p1.norm - p2.norm) < (double).001 ) && 00552 ( ABS (p1.DD-p2.DD) < (double).001 ); 00553 } 00554 00560 static bool PlanesClose (const csDPlane& p1, const csDPlane& p2); 00561 }; 00562 00567 class csDSquaredDist 00568 { 00569 public: 00571 static double PointPoint (const csDVector3& p1, const csDVector3& p2) 00572 { return dSqr (p1.x - p2.x) + dSqr (p1.y - p2.y) + dSqr (p1.z - p2.z); } 00573 00575 static double PointLine (const csDVector3& p, 00576 const csDVector3& l1, const csDVector3& l2); 00577 00579 static double PointPlane (const csDVector3& p, const csDPlane& plane) 00580 { double r = plane.Classify (p); return r * r; } 00581 00588 static double PointPoly (const csDVector3& p, csDVector3 *V, int n, 00589 const csDPlane& plane, double sqdist = -1); 00590 }; 00591 00597 class csDIntersect3 00598 { 00599 public: 00604 static void Plane ( 00605 const csDVector3& u, const csDVector3& v, // segment 00606 const csDVector3& normal, const csDVector3& a, // plane 00607 csDVector3& isect); // intersection point 00608 00617 static bool Plane ( 00618 const csDVector3& u, const csDVector3& v, // segment 00619 double A, double B, double C, double D, // plane Ax+By+Cz+D=0 00620 csDVector3& isect, // intersection point 00621 double& dist); // distance from u to isect 00622 00631 static bool Plane ( 00632 const csDVector3& u, const csDVector3& v, // segment 00633 const csDPlane& p, // plane Ax+By+Cz+D=0 00634 csDVector3& isect, // intersection point 00635 double& dist); // distance from u to isect 00636 00642 static bool Planes(const csDPlane& p1, const csDPlane& p2, 00643 const csDPlane& p3, csDVector3& isect); 00644 00651 static double Z0Plane ( 00652 const csDVector3& u, const csDVector3& v, // segment 00653 csDVector3& isect); // intersection point 00654 00661 static double ZPlane (double zval, // plane z = zval 00662 const csDVector3& u, const csDVector3& v, // segment 00663 csDVector3& isect); // intersection point 00664 00669 static double XFrustum ( 00670 double A, const csDVector3& u, const csDVector3& v, csDVector3& isect); 00671 00676 static double YFrustum ( 00677 double B, const csDVector3& u, const csDVector3& v, csDVector3& isect); 00678 }; 00679 00682 #endif // __CS_MATH3D_D_H__
Generated for Crystal Space by doxygen 1.2.18