00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 #ifndef AMOD_MATH_LIB_INCPLANE_H
00024 
00026 #define AMOD_MATH_LIB_INCPLANE_H
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00044 
00045 #include "point2d.H"
00046 #include "point3d.H"
00047 #include "line3d.H"
00048 
00049 template <class PLANE, class P, class V, class L>
00050 class _plane
00051 {
00052 protected:
00053     V       _normal;
00054     Greal  _d;
00055 
00056 public:
00057 
00058     _plane()                     :                        _d(0) {}
00059     _plane(const V &n, Greal d) : _normal(n.normalize()),_d(d) {}
00060     _plane(const P &p, const V&n): _normal(n.normalize()),_d((P()-p)*_normal) {}
00061     _plane(const P &p1,  const P&p2, const P&p3)  
00062            { *this = _plane<PLANE,P,V,L>(p1, cross(p3-p1, p2-p1)); }
00063     _plane(const P &,  const V&, const V&);
00064 
00065     
00066     
00067     
00068     
00069     _plane(const P plg[], int n);
00070 
00071     
00072     
00073     
00074     _plane(const P plg[], int n, const V& normal);
00075 
00076     PLANE    operator -()          const { return PLANE(-_normal, -_d); }
00077     Greal   dist      (const P &p)const { return (p-P())*_normal+_d; }
00078     P        project   (const P & )const;
00079     V        project   (const V & )const;
00080     L        project   (const L & )const;
00081 
00082     P        operator* (const L & )const;
00083 
00084           V &normal    ()                { return _normal; }
00085     const V &normal    ()          const { return _normal; }
00086     Greal  &d         ()                { return _d; }
00087     Greal   d         ()          const { return _d; }
00088     P        origin    ()          const { return P()-_normal*_d; }
00089 
00090     bool     isParallel(const PLANE &p) const { return _normal.isEqual(p._normal)||
00091                                                        _normal.isEqual(-p._normal); }
00092     bool     isEqual   (const PLANE &p) const { return (_d*_normal).isEqual(
00093                                                         p._d*p._normal);  }
00094     bool     isValid   ()          const { return fabs(_normal.length() - 1) <
00095                                    epsNorMath(); }
00096 
00097     void     orthoplane(int& i1, int& i2)          const;
00098     void     orthoplane(int& i1, int& i2, int& i3) const;
00099 
00100     P        intersect(const L &l) const { return plane_intersect(l.point(), 
00101                                             l.vector(), origin(), _normal); }
00102 
00103 }; 
00104 
00105 template <class P, class V> 
00106 inline
00107 P        
00108 plane_intersect(
00109    const P &pt, 
00110    const V &D, 
00111    const P &O, 
00112    const V &N)
00113 {
00114    Greal t = (fabs(D*N) > 0.000001) ? ((O-pt) * N) / (D*N) : -1; 
00115 
00116    return pt + t * D; 
00117 }
00118 
00119 template <class P, class V> 
00120 inline
00121 Greal
00122 axis_ang( 
00123    const P &p1, 
00124    const P &p2, 
00125    const P &axispt, 
00126    const V &axis)
00127 {
00128    V v1 = (p1 - axispt).normalize();
00129    V v2 = (p2 - axispt).normalize();
00130    const Greal negone = -1.0;
00131    const Greal one    =  1.0;
00132    Greal ang = acos(clamp(v1*v2, negone, one));
00133    if (cross(v1,v2) * axis < 0)
00134       ang = -ang;
00135    return ang;
00136 }
00137 
00138 #ifdef GLUE_NEEDS_TEMPLATES_IN_H_FILE
00139 #include "plane.C"
00140 #endif
00141 #endif