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 <[email protected]> 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 "csextern.h" 00025 00026 #include "cstypes.h" 00027 00035 #ifndef ABS 00036 #define ABS(x) ((x)<0?-(x):(x)) 00037 #endif 00038 00039 class csDVector3; 00040 class csDMatrix3; 00041 class csVector3; 00042 00043 inline double dSqr (double d) 00044 { 00045 return d * d; 00046 } 00047 00051 class CS_CRYSTALSPACE_EXPORT csDVector3 00052 { 00053 public: 00055 double x; 00057 double y; 00059 double z; 00060 00066 csDVector3 () {} 00067 00073 csDVector3 (double m) : x(m), y(m), z(m) {} 00074 00076 csDVector3 (double ix, double iy, double iz = 0) { x = ix; y = iy; z = iz; } 00077 00079 csDVector3 (const csDVector3& v) { x = v.x; y = v.y; z = v.z; } 00080 00082 csDVector3 (const csVector3&); 00083 00085 inline friend 00086 csDVector3 operator+ (const csDVector3& v1, const csDVector3& v2) 00087 { return csDVector3(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 { return csDVector3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); } 00093 00095 inline friend double operator* (const csDVector3& v1, const csDVector3& v2) 00096 { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; } 00097 00099 inline friend 00100 csDVector3 operator% (const csDVector3& v1, const csDVector3& v2) 00101 { 00102 return csDVector3 (v1.y*v2.z-v1.z*v2.y, 00103 v1.z*v2.x-v1.x*v2.z, 00104 v1.x*v2.y-v1.y*v2.x); 00105 } 00106 00108 void Cross (const csDVector3 & px, const csDVector3 & py) 00109 { 00110 x = px.y*py.z - px.z*py.y; 00111 y = px.z*py.x - px.x*py.z; 00112 z = px.x*py.y - px.y*py.x; 00113 } 00114 00116 inline friend csDVector3 operator* (const csDVector3& v, double f) 00117 { return csDVector3(v.x*f, v.y*f, v.z*f); } 00118 00120 inline friend csDVector3 operator* (double f, const csDVector3& v) 00121 { return csDVector3(v.x*f, v.y*f, v.z*f); } 00122 00124 inline friend csDVector3 operator/ (const csDVector3& v, double f) 00125 { f = 1.0f/f; return csDVector3(v.x*f, v.y*f, v.z*f); } 00126 00128 inline friend bool operator== (const csDVector3& v1, const csDVector3& v2) 00129 { return v1.x==v2.x && v1.y==v2.y && v1.z==v2.z; } 00130 00132 inline friend bool operator!= (const csDVector3& v1, const csDVector3& v2) 00133 { return v1.x!=v2.x || v1.y!=v2.y || v1.z!=v2.z; } 00134 00136 inline friend 00137 csDVector3 operator>> (const csDVector3& v1, const csDVector3& v2) 00138 { return v2*(v1*v2)/(v2*v2); } 00139 00141 inline friend 00142 csDVector3 operator<< (const csDVector3& v1, const csDVector3& v2) 00143 { return v1*(v1*v2)/(v1*v1); } 00144 00146 inline friend bool operator< (const csDVector3& v, double f) 00147 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f; } 00148 00150 inline friend bool operator> (double f, const csDVector3& v) 00151 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f; } 00152 00154 inline double operator[](int n) const {return !n?x:n&1?y:z;} 00155 00157 inline double & operator[](int n){return !n?x:n&1?y:z;} 00158 00160 inline csDVector3& operator+= (const csDVector3& v) 00161 { 00162 x += v.x; 00163 y += v.y; 00164 z += v.z; 00165 00166 return *this; 00167 } 00168 00170 inline csDVector3& operator-= (const csDVector3& v) 00171 { 00172 x -= v.x; 00173 y -= v.y; 00174 z -= v.z; 00175 00176 return *this; 00177 } 00178 00180 inline csDVector3& operator*= (double f) 00181 { x *= f; y *= f; z *= f; return *this; } 00182 00184 inline csDVector3& operator/= (double f) 00185 { x /= f; y /= f; z /= f; return *this; } 00186 00188 inline csDVector3 operator+ () const { return *this; } 00189 00191 inline csDVector3 operator- () const { return csDVector3(-x,-y,-z); } 00192 00194 inline void Set (double sx, double sy, double sz) { x = sx; y = sy; z = sz; } 00195 00197 double Norm () const; 00198 00200 double SquaredNorm () const; 00201 00207 csDVector3 Unit () const { return (*this)/(this->Norm()); } 00208 00210 inline static double Norm (const csDVector3& v) { return v.Norm(); } 00211 00213 inline static csDVector3 Unit (const csDVector3& v) { return v.Unit(); } 00214 00216 void Normalize(); 00217 }; 00218 00219 00223 class CS_CRYSTALSPACE_EXPORT csDMatrix3 00224 { 00225 public: 00226 double m11, m12, m13; 00227 double m21, m22, m23; 00228 double m31, m32, m33; 00229 00230 public: 00232 csDMatrix3 (); 00233 00235 csDMatrix3 (double m11, double m12, double m13, 00236 double m21, double m22, double m23, 00237 double m31, double m32, double m33); 00238 00240 inline csDVector3 Row1() const { return csDVector3 (m11,m12,m13); } 00241 00243 inline csDVector3 Row2() const { return csDVector3 (m21,m22,m23); } 00244 00246 inline csDVector3 Row3() const { return csDVector3 (m31,m32,m33); } 00247 00249 inline csDVector3 Col1() const { return csDVector3 (m11,m21,m31); } 00250 00252 inline csDVector3 Col2() const { return csDVector3 (m12,m22,m32); } 00253 00255 inline csDVector3 Col3() const { return csDVector3 (m13,m23,m33); } 00256 00258 inline void Set (double m11, double m12, double m13, 00259 double m21, double m22, double m23, 00260 double m31, double m32, double m33) 00261 { 00262 csDMatrix3::m11 = m11; csDMatrix3::m12 = m12; csDMatrix3::m13 = m13; 00263 csDMatrix3::m21 = m21; csDMatrix3::m22 = m22; csDMatrix3::m23 = m23; 00264 csDMatrix3::m31 = m31; csDMatrix3::m32 = m32; csDMatrix3::m33 = m33; 00265 } 00266 00268 csDMatrix3& operator+= (const csDMatrix3& m); 00269 00271 csDMatrix3& operator-= (const csDMatrix3& m); 00272 00274 csDMatrix3& operator*= (const csDMatrix3& m); 00275 00277 csDMatrix3& operator*= (double s); 00278 00280 csDMatrix3& operator/= (double s); 00281 00283 inline csDMatrix3 operator+ () const { return *this; } 00285 inline csDMatrix3 operator- () const 00286 { 00287 return csDMatrix3(-m11,-m12,-m13, 00288 -m21,-m22,-m23, 00289 -m31,-m32,-m33); 00290 } 00291 00293 void Transpose (); 00294 00296 csDMatrix3 GetTranspose () const; 00297 00299 inline csDMatrix3 GetInverse () const 00300 { 00301 csDMatrix3 C( 00302 (m22*m33 - m23*m32), -(m12*m33 - m13*m32), (m12*m23 - m13*m22), 00303 -(m21*m33 - m23*m31), (m11*m33 - m13*m31), -(m11*m23 - m13*m21), 00304 (m21*m32 - m22*m31), -(m11*m32 - m12*m31), (m11*m22 - m12*m21) ); 00305 double s = (double)1./(m11*C.m11 + m12*C.m21 + m13*C.m31); 00306 00307 C *= s; 00308 00309 return C; 00310 } 00311 00313 void Invert() { *this = GetInverse (); } 00314 00316 double Determinant () const; 00317 00319 void Identity (); 00320 00322 friend csDMatrix3 operator+ (const csDMatrix3& m1, const csDMatrix3& m2); 00324 friend csDMatrix3 operator- (const csDMatrix3& m1, const csDMatrix3& m2); 00326 friend csDMatrix3 operator* (const csDMatrix3& m1, const csDMatrix3& m2); 00327 00329 inline friend csDVector3 operator* (const csDMatrix3& m, const csDVector3& v) 00330 { 00331 return csDVector3 (m.m11*v.x + m.m12*v.y + m.m13*v.z, 00332 m.m21*v.x + m.m22*v.y + m.m23*v.z, 00333 m.m31*v.x + m.m32*v.y + m.m33*v.z); 00334 } 00335 00337 friend csDMatrix3 operator* (const csDMatrix3& m, double f); 00339 friend csDMatrix3 operator* (double f, const csDMatrix3& m); 00341 friend csDMatrix3 operator/ (const csDMatrix3& m, double f); 00343 friend bool operator== (const csDMatrix3& m1, const csDMatrix3& m2); 00345 friend bool operator!= (const csDMatrix3& m1, const csDMatrix3& m2); 00347 friend bool operator< (const csDMatrix3& m, double f); 00349 friend bool operator> (double f, const csDMatrix3& m); 00350 }; 00351 00352 00358 class CS_CRYSTALSPACE_EXPORT csDPlane 00359 { 00360 public: 00362 csDVector3 norm; 00363 00365 double DD; 00366 00368 csDPlane () : norm(0,0,1), DD(0) {} 00369 00371 csDPlane (const csDVector3& plane_norm, double d=0) : 00372 norm(plane_norm), DD(d) {} 00373 00375 csDPlane (double a, double b, double c, double d=0) : norm(a,b,c), DD(d) {} 00376 00378 inline csDVector3& Normal () { return norm; } 00380 inline const csDVector3& Normal () const { return norm; } 00381 00383 inline double A () const { return norm.x; } 00385 inline double B () const { return norm.y; } 00387 inline double C () const { return norm.z; } 00389 inline double D () const { return DD; } 00390 00392 inline double& A () { return norm.x; } 00394 inline double& B () { return norm.y; } 00396 inline double& C () { return norm.z; } 00398 inline double& D () { return DD; } 00399 00401 inline void Set (double a, double b, double c, double d) 00402 { norm.x = a; norm.y = b; norm.z = c; DD = d; } 00403 00405 inline double Classify (const csDVector3& pt) const { return norm*pt+DD; } 00406 00408 static double Classify (double A, double B, double C, double D, 00409 const csDVector3& pt) 00410 { return A*pt.x + B*pt.y + C*pt.z + D; } 00411 00417 inline double Distance (const csDVector3& pt) const 00418 { return ABS (Classify (pt)); } 00419 00421 void Invert () { norm = -norm; DD = -DD; } 00422 00424 void Normalize () 00425 { 00426 double f = norm.Norm (); 00427 if (f) { norm /= f; DD /= f; } 00428 } 00429 00430 }; 00431 00436 class CS_CRYSTALSPACE_EXPORT csDMath3 00437 { 00438 public: 00446 static int WhichSide3D (const csDVector3& p, 00447 const csDVector3& v1, const csDVector3& v2) 00448 { 00449 // double s = p * (v1%v2); (original expression: expanded to the below:) 00450 double s = p.x*(v1.y*v2.z-v1.z*v2.y) + p.y*(v1.z*v2.x-v1.x*v2.z) + 00451 p.z*(v1.x*v2.y-v1.y*v2.x); 00452 if (s < 0) return 1; 00453 else if (s > 0) return -1; 00454 else return 0; 00455 } 00456 00462 static bool Visible (const csDVector3& p, const csDVector3& t1, 00463 const csDVector3& t2, const csDVector3& t3); 00464 00470 static bool Visible (const csDVector3& p, const csDPlane& pl) 00471 { return pl.Classify (p) <= 0; } 00472 00482 static void Between (const csDVector3& v1, const csDVector3& v2, 00483 csDVector3& v, double pct, double wid); 00484 00491 static void SetMinMax (const csDVector3& v, 00492 csDVector3& min, csDVector3& max) 00493 { 00494 if (v.x > max.x) max.x = v.x; else if (v.x < min.x ) min.x = v.x; 00495 if (v.y > max.y) max.y = v.y; else if (v.y < min.y ) min.y = v.y; 00496 if (v.z > max.z) max.z = v.z; else if (v.z < min.z ) min.z = v.z; 00497 } 00498 00504 inline static double DoubleArea3 (const csDVector3 &a, const csDVector3 &b, 00505 const csDVector3 &c) 00506 { 00507 csDVector3 v1 = b - a; 00508 csDVector3 v2 = c - a; 00509 return (v1 % v2).Norm (); 00510 } 00511 00517 inline static void CalcNormal (csDVector3& norm, const csDVector3& v1, 00518 const csDVector3& v2, const csDVector3& v3) 00519 { 00520 norm = (v1-v2)%(v1-v3); 00521 } 00522 00528 static void CalcNormal (csDVector3& norm, 00529 const csDVector3& v, const csDVector3& u) 00530 { norm = u%v; /* NOT v%u - vertexes are defined clockwise */ } 00531 00538 static void CalcPlane (const csDVector3& v1, const csDVector3& v2, 00539 const csDVector3& v3, csDVector3& normal, double& D) 00540 { 00541 normal = (v1-v2)%(v1-v3); 00542 D = - (normal * v1); 00543 } 00544 00551 static bool PlanesEqual (const csDPlane& p1, const csDPlane& p2) 00552 { 00553 return ( ( p1.norm - p2.norm) < (double).001 ) && 00554 ( ABS (p1.DD-p2.DD) < (double).001 ); 00555 } 00556 00562 static bool PlanesClose (const csDPlane& p1, const csDPlane& p2); 00563 }; 00564 00569 class CS_CRYSTALSPACE_EXPORT csDSquaredDist 00570 { 00571 public: 00573 static double PointPoint (const csDVector3& p1, const csDVector3& p2) 00574 { return dSqr (p1.x - p2.x) + dSqr (p1.y - p2.y) + dSqr (p1.z - p2.z); } 00575 00577 static double PointLine (const csDVector3& p, 00578 const csDVector3& l1, const csDVector3& l2); 00579 00581 static double PointPlane (const csDVector3& p, const csDPlane& plane) 00582 { double r = plane.Classify (p); return r * r; } 00583 00590 static double PointPoly (const csDVector3& p, csDVector3 *V, int n, 00591 const csDPlane& plane, double sqdist = -1); 00592 }; 00593 00599 class CS_CRYSTALSPACE_EXPORT csDIntersect3 00600 { 00601 public: 00606 static void Plane ( 00607 const csDVector3& u, const csDVector3& v, // segment 00608 const csDVector3& normal, const csDVector3& a, // plane 00609 csDVector3& isect); // intersection point 00610 00619 static bool Plane ( 00620 const csDVector3& u, const csDVector3& v, // segment 00621 double A, double B, double C, double D, // plane Ax+By+Cz+D=0 00622 csDVector3& isect, // intersection point 00623 double& dist); // distance from u to isect 00624 00633 static bool Plane ( 00634 const csDVector3& u, const csDVector3& v, // segment 00635 const csDPlane& p, // plane Ax+By+Cz+D=0 00636 csDVector3& isect, // intersection point 00637 double& dist); // distance from u to isect 00638 00644 static bool Planes(const csDPlane& p1, const csDPlane& p2, 00645 const csDPlane& p3, csDVector3& isect); 00646 00653 static double Z0Plane ( 00654 const csDVector3& u, const csDVector3& v, // segment 00655 csDVector3& isect); // intersection point 00656 00663 static double ZPlane (double zval, // plane z = zval 00664 const csDVector3& u, const csDVector3& v, // segment 00665 csDVector3& isect); // intersection point 00666 00671 static double XFrustum ( 00672 double A, const csDVector3& u, const csDVector3& v, csDVector3& isect); 00673 00678 static double YFrustum ( 00679 double B, const csDVector3& u, const csDVector3& v, csDVector3& isect); 00680 }; 00681 00684 #endif // __CS_MATH3D_D_H__
Generated for Crystal Space by doxygen 1.4.7