|
math3d_d.h00001 /* 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 00026 #ifndef ABS 00027 #define ABS(x) ((x)<0?-(x):(x)) 00028 #endif 00029 00030 class csDVector3; 00031 class csDMatrix3; 00032 class csVector3; 00033 00034 inline double dSqr (double d) 00035 { 00036 return d * d; 00037 } 00038 00042 class csDVector3 00043 { 00044 public: 00046 double x; 00048 double y; 00050 double z; 00051 00057 csDVector3 () {} 00058 00064 csDVector3 (double m) : x(m), y(m), z(m) {} 00065 00067 csDVector3 (double ix, double iy, double iz = 0) { x = ix; y = iy; z = iz; } 00068 00070 csDVector3 (const csDVector3& v) { x = v.x; y = v.y; z = v.z; } 00071 00073 csDVector3 (const csVector3&); 00074 00076 inline friend 00077 csDVector3 operator+ (const csDVector3& v1, const csDVector3& v2) 00078 { return csDVector3(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); } 00079 00081 inline friend 00082 csDVector3 operator- (const csDVector3& v1, const csDVector3& v2) 00083 { return csDVector3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); } 00084 00086 inline friend double operator* (const csDVector3& v1, const csDVector3& v2) 00087 { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; } 00088 00090 inline friend 00091 csDVector3 operator% (const csDVector3& v1, const csDVector3& v2) 00092 { 00093 return csDVector3 (v1.y*v2.z-v1.z*v2.y, 00094 v1.z*v2.x-v1.x*v2.z, 00095 v1.x*v2.y-v1.y*v2.x); 00096 } 00097 00099 void Cross (const csDVector3 & px, const csDVector3 & py) 00100 { 00101 x = px.y*py.z - px.z*py.y; 00102 y = px.z*py.x - px.x*py.z; 00103 z = px.x*py.y - px.y*py.x; 00104 } 00105 00107 inline friend csDVector3 operator* (const csDVector3& v, double f) 00108 { return csDVector3(v.x*f, v.y*f, v.z*f); } 00109 00111 inline friend csDVector3 operator* (double f, const csDVector3& v) 00112 { return csDVector3(v.x*f, v.y*f, v.z*f); } 00113 00115 inline friend csDVector3 operator/ (const csDVector3& v, double f) 00116 { f = 1.0f/f; return csDVector3(v.x*f, v.y*f, v.z*f); } 00117 00119 inline friend bool operator== (const csDVector3& v1, const csDVector3& v2) 00120 { return v1.x==v2.x && v1.y==v2.y && v1.z==v2.z; } 00121 00123 inline friend bool operator!= (const csDVector3& v1, const csDVector3& v2) 00124 { return v1.x!=v2.x || v1.y!=v2.y || v1.z!=v2.z; } 00125 00127 inline friend 00128 csDVector3 operator>> (const csDVector3& v1, const csDVector3& v2) 00129 { return v2*(v1*v2)/(v2*v2); } 00130 00132 inline friend 00133 csDVector3 operator<< (const csDVector3& v1, const csDVector3& v2) 00134 { return v1*(v1*v2)/(v1*v1); } 00135 00137 inline friend bool operator< (const csDVector3& v, double f) 00138 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f; } 00139 00141 inline friend bool operator> (double f, const csDVector3& v) 00142 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f; } 00143 00145 inline double operator[](int n) const {return !n?x:n&1?y:z;} 00146 00148 inline double & operator[](int n){return !n?x:n&1?y:z;} 00149 00151 inline csDVector3& operator+= (const csDVector3& v) 00152 { 00153 x += v.x; 00154 y += v.y; 00155 z += v.z; 00156 00157 return *this; 00158 } 00159 00161 inline csDVector3& operator-= (const csDVector3& v) 00162 { 00163 x -= v.x; 00164 y -= v.y; 00165 z -= v.z; 00166 00167 return *this; 00168 } 00169 00171 inline csDVector3& operator*= (double f) 00172 { x *= f; y *= f; z *= f; return *this; } 00173 00175 inline csDVector3& operator/= (double f) 00176 { x /= f; y /= f; z /= f; return *this; } 00177 00179 inline csDVector3 operator+ () const { return *this; } 00180 00182 inline csDVector3 operator- () const { return csDVector3(-x,-y,-z); } 00183 00185 inline void Set (double sx, double sy, double sz) { x = sx; y = sy; z = sz; } 00186 00188 double Norm () const; 00189 00195 csDVector3 Unit () const { return (*this)/(this->Norm()); } 00196 00198 inline static double Norm (const csDVector3& v) { return v.Norm(); } 00199 00201 inline static csDVector3 Unit (const csDVector3& v) { return v.Unit(); } 00202 00204 void Normalize(); 00205 }; 00206 00207 00211 class csDMatrix3 00212 { 00213 public: 00214 double m11, m12, m13; 00215 double m21, m22, m23; 00216 double m31, m32, m33; 00217 00218 public: 00220 csDMatrix3 (); 00221 00223 csDMatrix3 (double m11, double m12, double m13, 00224 double m21, double m22, double m23, 00225 double m31, double m32, double m33); 00226 00228 inline csDVector3 Row1() const { return csDVector3 (m11,m12,m13); } 00229 00231 inline csDVector3 Row2() const { return csDVector3 (m21,m22,m23); } 00232 00234 inline csDVector3 Row3() const { return csDVector3 (m31,m32,m33); } 00235 00237 inline csDVector3 Col1() const { return csDVector3 (m11,m21,m31); } 00238 00240 inline csDVector3 Col2() const { return csDVector3 (m12,m22,m32); } 00241 00243 inline csDVector3 Col3() const { return csDVector3 (m13,m23,m33); } 00244 00246 inline void Set (double m11, double m12, double m13, 00247 double m21, double m22, double m23, 00248 double m31, double m32, double m33) 00249 { 00250 csDMatrix3::m11 = m11; csDMatrix3::m12 = m12; csDMatrix3::m13 = m13; 00251 csDMatrix3::m21 = m21; csDMatrix3::m22 = m22; csDMatrix3::m23 = m23; 00252 csDMatrix3::m31 = m31; csDMatrix3::m32 = m32; csDMatrix3::m33 = m33; 00253 } 00254 00256 csDMatrix3& operator+= (const csDMatrix3& m); 00257 00259 csDMatrix3& operator-= (const csDMatrix3& m); 00260 00262 csDMatrix3& operator*= (const csDMatrix3& m); 00263 00265 csDMatrix3& operator*= (double s); 00266 00268 csDMatrix3& operator/= (double s); 00269 00271 inline csDMatrix3 operator+ () const { return *this; } 00273 inline csDMatrix3 operator- () const 00274 { 00275 return csDMatrix3(-m11,-m12,-m13, 00276 -m21,-m22,-m23, 00277 -m31,-m32,-m33); 00278 } 00279 00281 void Transpose (); 00282 00284 csDMatrix3 GetTranspose () const; 00285 00287 inline csDMatrix3 GetInverse () const 00288 { 00289 csDMatrix3 C( 00290 (m22*m33 - m23*m32), -(m12*m33 - m13*m32), (m12*m23 - m13*m22), 00291 -(m21*m33 - m23*m31), (m11*m33 - m13*m31), -(m11*m23 - m13*m21), 00292 (m21*m32 - m22*m31), -(m11*m32 - m12*m31), (m11*m22 - m12*m21) ); 00293 double s = (double)1./(m11*C.m11 + m12*C.m21 + m13*C.m31); 00294 00295 C *= s; 00296 00297 return C; 00298 } 00299 00301 void Invert() { *this = GetInverse (); } 00302 00304 double Determinant () const; 00305 00307 void Identity (); 00308 00310 friend csDMatrix3 operator+ (const csDMatrix3& m1, const csDMatrix3& m2); 00312 friend csDMatrix3 operator- (const csDMatrix3& m1, const csDMatrix3& m2); 00314 friend csDMatrix3 operator* (const csDMatrix3& m1, const csDMatrix3& m2); 00315 00317 inline friend csDVector3 operator* (const csDMatrix3& m, const csDVector3& v) 00318 { 00319 return csDVector3 (m.m11*v.x + m.m12*v.y + m.m13*v.z, 00320 m.m21*v.x + m.m22*v.y + m.m23*v.z, 00321 m.m31*v.x + m.m32*v.y + m.m33*v.z); 00322 } 00323 00325 friend csDMatrix3 operator* (const csDMatrix3& m, double f); 00327 friend csDMatrix3 operator* (double f, const csDMatrix3& m); 00329 friend csDMatrix3 operator/ (const csDMatrix3& m, double f); 00331 friend bool operator== (const csDMatrix3& m1, const csDMatrix3& m2); 00333 friend bool operator!= (const csDMatrix3& m1, const csDMatrix3& m2); 00335 friend bool operator< (const csDMatrix3& m, double f); 00337 friend bool operator> (double f, const csDMatrix3& m); 00338 }; 00339 00340 00346 class csDPlane 00347 { 00348 public: 00350 csDVector3 norm; 00351 00353 double DD; 00354 00356 csDPlane () : norm(0,0,1), DD(0) {} 00357 00359 csDPlane (const csDVector3& plane_norm, double d=0) : 00360 norm(plane_norm), DD(d) {} 00361 00363 csDPlane (double a, double b, double c, double d=0) : norm(a,b,c), DD(d) {} 00364 00366 inline csDVector3& Normal () { return norm; } 00368 inline const csDVector3& Normal () const { return norm; } 00369 00371 inline double A () const { return norm.x; } 00373 inline double B () const { return norm.y; } 00375 inline double C () const { return norm.z; } 00377 inline double D () const { return DD; } 00378 00380 inline double& A () { return norm.x; } 00382 inline double& B () { return norm.y; } 00384 inline double& C () { return norm.z; } 00386 inline double& D () { return DD; } 00387 00389 inline void Set (double a, double b, double c, double d) 00390 { norm.x = a; norm.y = b; norm.z = c; DD = d; } 00391 00393 inline double Classify (const csDVector3& pt) const { return norm*pt+DD; } 00394 00396 static double Classify (double A, double B, double C, double D, 00397 const csDVector3& pt) 00398 { return A*pt.x + B*pt.y + C*pt.z + D; } 00399 00405 inline double Distance (const csDVector3& pt) const 00406 { return ABS (Classify (pt)); } 00407 00409 void Invert () { norm = -norm; DD = -DD; } 00410 00412 void Normalize () 00413 { 00414 double f = norm.Norm (); 00415 if (f) { norm /= f; DD /= f; } 00416 } 00417 00418 }; 00419 00424 class csDMath3 00425 { 00426 public: 00434 static int WhichSide3D (const csDVector3& p, 00435 const csDVector3& v1, const csDVector3& v2) 00436 { 00437 // double s = p * (v1%v2); (original expression: expanded to the below:) 00438 double s = p.x*(v1.y*v2.z-v1.z*v2.y) + p.y*(v1.z*v2.x-v1.x*v2.z) + 00439 p.z*(v1.x*v2.y-v1.y*v2.x); 00440 if (s < 0) return 1; 00441 else if (s > 0) return -1; 00442 else return 0; 00443 } 00444 00450 static bool Visible (const csDVector3& p, const csDVector3& t1, 00451 const csDVector3& t2, const csDVector3& t3); 00452 00458 static bool Visible (const csDVector3& p, const csDPlane& pl) 00459 { return pl.Classify (p) <= 0; } 00460 00470 static void Between (const csDVector3& v1, const csDVector3& v2, 00471 csDVector3& v, double pct, double wid); 00472 00479 static void SetMinMax (const csDVector3& v, 00480 csDVector3& min, csDVector3& max) 00481 { 00482 if (v.x > max.x) max.x = v.x; else if (v.x < min.x ) min.x = v.x; 00483 if (v.y > max.y) max.y = v.y; else if (v.y < min.y ) min.y = v.y; 00484 if (v.z > max.z) max.z = v.z; else if (v.z < min.z ) min.z = v.z; 00485 } 00486 00492 inline static double Area3 (const csDVector3 &a, const csDVector3 &b, 00493 const csDVector3 &c) 00494 { 00495 csDVector3 v1 = b - a; 00496 csDVector3 v2 = c - a; 00497 return ((v1.y * v2.z + v1.z * v2.x + v1.x * v2.y) - 00498 (v1.y * v2.x + v1.x * v2.z + v1.z * v2.y)); 00499 } 00500 00506 inline static void CalcNormal (csDVector3& norm, const csDVector3& v1, 00507 const csDVector3& v2, const csDVector3& v3) 00508 { 00509 norm = (v1-v2)%(v1-v3); 00510 } 00511 00517 static void CalcNormal (csDVector3& norm, 00518 const csDVector3& v, const csDVector3& u) 00519 { norm = u%v; /* NOT v%u - vertexes are defined clockwise */ } 00520 00527 static void CalcPlane (const csDVector3& v1, const csDVector3& v2, 00528 const csDVector3& v3, csDVector3& normal, double& D) 00529 { 00530 normal = (v1-v2)%(v1-v3); 00531 D = - (normal * v1); 00532 } 00533 00540 static bool PlanesEqual (const csDPlane& p1, const csDPlane& p2) 00541 { 00542 return ( ( p1.norm - p2.norm) < (double).001 ) && 00543 ( ABS (p1.DD-p2.DD) < (double).001 ); 00544 } 00545 00551 static bool PlanesClose (const csDPlane& p1, const csDPlane& p2); 00552 }; 00553 00558 class csDSquaredDist 00559 { 00560 public: 00562 static double PointPoint (const csDVector3& p1, const csDVector3& p2) 00563 { return dSqr (p1.x - p2.x) + dSqr (p1.y - p2.y) + dSqr (p1.z - p2.z); } 00564 00566 static double PointLine (const csDVector3& p, 00567 const csDVector3& l1, const csDVector3& l2); 00568 00570 static double PointPlane (const csDVector3& p, const csDPlane& plane) 00571 { double r = plane.Classify (p); return r * r; } 00572 00579 static double PointPoly (const csDVector3& p, csDVector3 *V, int n, 00580 const csDPlane& plane, double sqdist = -1); 00581 }; 00582 00588 class csDIntersect3 00589 { 00590 public: 00595 static void Plane ( 00596 const csDVector3& u, const csDVector3& v, // segment 00597 const csDVector3& normal, const csDVector3& a, // plane 00598 csDVector3& isect); // intersection point 00599 00608 static bool Plane ( 00609 const csDVector3& u, const csDVector3& v, // segment 00610 double A, double B, double C, double D, // plane Ax+By+Cz+D=0 00611 csDVector3& isect, // intersection point 00612 double& dist); // distance from u to isect 00613 00622 static bool Plane ( 00623 const csDVector3& u, const csDVector3& v, // segment 00624 const csDPlane& p, // plane Ax+By+Cz+D=0 00625 csDVector3& isect, // intersection point 00626 double& dist); // distance from u to isect 00627 00633 static bool Planes(const csDPlane& p1, const csDPlane& p2, 00634 const csDPlane& p3, csDVector3& isect); 00635 00642 static double Z0Plane ( 00643 const csDVector3& u, const csDVector3& v, // segment 00644 csDVector3& isect); // intersection point 00645 00652 static double ZPlane (double zval, // plane z = zval 00653 const csDVector3& u, const csDVector3& v, // segment 00654 csDVector3& isect); // intersection point 00655 00660 static double XFrustum ( 00661 double A, const csDVector3& u, const csDVector3& v, csDVector3& isect); 00662 00667 static double YFrustum ( 00668 double B, const csDVector3& u, const csDVector3& v, csDVector3& isect); 00669 }; 00670 00671 #endif // __CS_MATH3D_D_H__ Generated for Crystal Space by doxygen 1.2.5 written by Dimitri van Heesch, ©1997-2000 |