Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

plane.C

Go to the documentation of this file.
00001 /*!
00002  *  \file Plane.C
00003  *  \brief Implementation of non-inline methods of class Plane.
00004  *  \ingroup group_MLIB
00005  *
00006  */
00007 
00008 #include "line.H"
00009 #include "plane.H"
00010 
00011 /* Constructors */
00012 
00013 template <class PLANE,class P,class V,class L>
00014 MLIB_INLINE
00015 mlib::Plane<PLANE,P,V,L>::Plane(const P &p,  const V&v1, const V&v2)
00016     : _d(0)
00017 {
00018    *this = Plane<PLANE,P,V,L>(p, cross(v1, v2));
00019 }
00020 
00021 /*!
00022  *  All polygon vertices are used to calculate the plane coefficients to
00023  *  make the formula symetrical.
00024  *
00025  */
00026 template <class PLANE,class P,class V,class L>
00027 MLIB_INLINE
00028 mlib::Plane<PLANE,P,V,L>::Plane(const P plg[], int n)
00029     : _d(0)
00030 {
00031     if (plg == NULL || n < 3)
00032         return;
00033 
00034     if (n == 4)
00035     {
00036         // More efficient code for 4-sided polygons
00037 
00038         const P a = plg[0];
00039         const P b = plg[1];
00040         const P c = plg[2];
00041         const P d = plg[3];
00042         
00043         _normal = V((c[1]-a[1])*(d[2]-b[2]) + (c[2]-a[2])*(b[1]-d[1]),
00044                         (c[2]-a[2])*(d[0]-b[0]) + (c[0]-a[0])*(b[2]-d[2]),
00045                         (c[0]-a[0])*(d[1]-b[1]) + (c[1]-a[1])*(b[0]-d[0]));
00046         
00047         _d      = -0.25*(_normal[0]*(a[0]+b[0]+c[0]+d[0])+
00048          _normal[1]*(a[1]+b[1]+c[1]+d[1])+
00049          _normal[2]*(a[2]+b[2]+c[2]+d[2]));
00050     } else {
00051 
00052         // General case for n-sided polygons
00053         
00054         P a;
00055         P b = plg[n-2];
00056         P c = plg[n-1];
00057         P s(0,0,0);
00058 
00059         for (int i = 0; i < n; i++)
00060         {
00061             a = b;
00062             b = c;
00063             c = plg[i];
00064 
00065             _normal += V(b[1] * (c[2]-a[2]),
00066                         b[2] * (c[0]-a[0]),
00067                         b[0] * (c[1]-a[1]));
00068 
00069            s += c;
00070    }
00071    
00072    _d = -((s-P()) * _normal) / n;
00073     }
00074 
00075     // Obtain the polygon area to be 1/2 of the length of the (non-normalized) 
00076     // normal vector of the plane
00077     //
00078     const double length = _normal.length();
00079 
00080     if (length > gEpsZeroMath) {
00081    _normal /= length;
00082         _d      /= length;
00083     } else {
00084         cerr << "plane::plane : degenerate plane specification" << endl;
00085         _normal = V();
00086         _d      = 0;
00087     }
00088 }
00089 
00090 template <class PLANE,class P,class V,class L>
00091 MLIB_INLINE
00092 mlib::Plane<PLANE,P,V,L>::Plane(const P plg[], int n, const V& nor)
00093      :_normal(nor.normalized()), _d(0)
00094 {
00095     if (plg == NULL || n < 1 || _normal.is_null())
00096         return;
00097 
00098     P s(0,0,0);
00099     
00100     for (int i = 0; i < n; i++)
00101         s += plg[i];
00102     
00103     _d = -((s-P()) * _normal) / n;
00104 }
00105 
00106 /* Projection Functions */
00107 
00108 template <class PLANE,class P,class V,class L>
00109 MLIB_INLINE
00110 P
00111 mlib::Plane<PLANE,P,V,L>::project(const P& p) const
00112 {
00113     return p - dist(p) * _normal;
00114 } 
00115 
00116 
00117 
00118 template <class PLANE,class P,class V,class L>
00119 MLIB_INLINE
00120 V 
00121 mlib::Plane<PLANE,P,V,L>::project(const V& v) const
00122 {
00123     return v - ((_normal * v) * _normal);
00124 } 
00125 
00126 
00127 
00128 template <class PLANE,class P,class V,class L>
00129 MLIB_INLINE
00130 L 
00131 mlib::Plane<PLANE,P,V,L>::project(const L& l) const
00132 {
00133     return L(project(l.point()), project(l.vector()));
00134 }

Generated on Mon Sep 18 11:39:32 2006 for jot by  doxygen 1.4.4