## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# 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 "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__