Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials
plane3d.h
Go to the documentation of this file.
00001 // Copyright (C) 2002-2010 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
00004 
00005 #ifndef __IRR_PLANE_3D_H_INCLUDED__
00006 #define __IRR_PLANE_3D_H_INCLUDED__
00007 
00008 #include "irrMath.h"
00009 #include "vector3d.h"
00010 
00011 namespace irr
00012 {
00013 namespace core
00014 {
00015 
00017 enum EIntersectionRelation3D
00018 {
00019         ISREL3D_FRONT = 0,
00020         ISREL3D_BACK,
00021         ISREL3D_PLANAR,
00022         ISREL3D_SPANNING,
00023         ISREL3D_CLIPPED
00024 };
00025 
00027 
00032 template <class T>
00033 class plane3d
00034 {
00035         public:
00036 
00037                 // Constructors
00038 
00039                 plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); }
00040                 
00041                 plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); }
00042                 
00043                 plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); }
00044                 
00045                 plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3)
00046                 { setPlane(point1, point2, point3); }
00047                 
00048                 plane3d(const vector3d<T> & normal, const T d) : Normal(normal), D(d) { }
00049 
00050                 // operators
00051 
00052                 inline bool operator==(const plane3d<T>& other) const { return (equals(D, other.D) && Normal==other.Normal);}
00053 
00054                 inline bool operator!=(const plane3d<T>& other) const { return !(*this == other);}
00055 
00056                 // functions
00057 
00058                 void setPlane(const vector3d<T>& point, const vector3d<T>& nvector)
00059                 {
00060                         Normal = nvector;
00061                         recalculateD(point);
00062                 }
00063 
00064                 void setPlane(const vector3d<T>& nvect, T d)
00065                 {
00066                         Normal = nvect;
00067                         D = d;
00068                 }
00069 
00070                 void setPlane(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3)
00071                 {
00072                         // creates the plane from 3 memberpoints
00073                         Normal = (point2 - point1).crossProduct(point3 - point1);
00074                         Normal.normalize();
00075 
00076                         recalculateD(point1);
00077                 }
00078 
00079 
00081 
00086                 bool getIntersectionWithLine(const vector3d<T>& linePoint,
00087                                 const vector3d<T>& lineVect,
00088                                 vector3d<T>& outIntersection) const
00089                 {
00090                         T t2 = Normal.dotProduct(lineVect);
00091 
00092                         if (t2 == 0)
00093                                 return false;
00094 
00095                         T t =- (Normal.dotProduct(linePoint) + D) / t2;
00096                         outIntersection = linePoint + (lineVect * t);
00097                         return true;
00098                 }
00099 
00101 
00107                 f32 getKnownIntersectionWithLine(const vector3d<T>& linePoint1,
00108                         const vector3d<T>& linePoint2) const
00109                 {
00110                         vector3d<T> vect = linePoint2 - linePoint1;
00111                         T t2 = (f32)Normal.dotProduct(vect);
00112                         return (f32)-((Normal.dotProduct(linePoint1) + D) / t2);
00113                 }
00114 
00116 
00121                 bool getIntersectionWithLimitedLine(
00122                                 const vector3d<T>& linePoint1,
00123                                 const vector3d<T>& linePoint2,
00124                                 vector3d<T>& outIntersection) const
00125                 {
00126                         return (getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) &&
00127                                         outIntersection.isBetweenPoints(linePoint1, linePoint2));
00128                 }
00129 
00131 
00135                 EIntersectionRelation3D classifyPointRelation(const vector3d<T>& point) const
00136                 {
00137                         const T d = Normal.dotProduct(point) + D;
00138 
00139                         if (d < -ROUNDING_ERROR_f32)
00140                                 return ISREL3D_BACK;
00141 
00142                         if (d > ROUNDING_ERROR_f32)
00143                                 return ISREL3D_FRONT;
00144 
00145                         return ISREL3D_PLANAR;
00146                 }
00147 
00149                 void recalculateD(const vector3d<T>& MPoint)
00150                 {
00151                         D = - MPoint.dotProduct(Normal);
00152                 }
00153 
00155                 vector3d<T> getMemberPoint() const
00156                 {
00157                         return Normal * -D;
00158                 }
00159 
00161 
00162                 bool existsIntersection(const plane3d<T>& other) const
00163                 {
00164                         vector3d<T> cross = other.Normal.crossProduct(Normal);
00165                         return cross.getLength() > core::ROUNDING_ERROR_f32;
00166                 }
00167 
00169 
00173                 bool getIntersectionWithPlane(const plane3d<T>& other,
00174                                 vector3d<T>& outLinePoint,
00175                                 vector3d<T>& outLineVect) const
00176                 {
00177                         const T fn00 = Normal.getLength();
00178                         const T fn01 = Normal.dotProduct(other.Normal);
00179                         const T fn11 = other.Normal.getLength();
00180                         const f64 det = fn00*fn11 - fn01*fn01;
00181 
00182                         if (fabs(det) < ROUNDING_ERROR_f64 )
00183                                 return false;
00184 
00185                         const f64 invdet = 1.0 / det;
00186                         const f64 fc0 = (fn11*-D + fn01*other.D) * invdet;
00187                         const f64 fc1 = (fn00*-other.D + fn01*D) * invdet;
00188 
00189                         outLineVect = Normal.crossProduct(other.Normal);
00190                         outLinePoint = Normal*(T)fc0 + other.Normal*(T)fc1;
00191                         return true;
00192                 }
00193 
00195                 bool getIntersectionWithPlanes(const plane3d<T>& o1,
00196                                 const plane3d<T>& o2, vector3d<T>& outPoint) const
00197                 {
00198                         vector3d<T> linePoint, lineVect;
00199                         if (getIntersectionWithPlane(o1, linePoint, lineVect))
00200                                 return o2.getIntersectionWithLine(linePoint, lineVect, outPoint);
00201 
00202                         return false;
00203                 }
00204 
00206 
00214                 bool isFrontFacing(const vector3d<T>& lookDirection) const
00215                 {
00216                         const f32 d = Normal.dotProduct(lookDirection);
00217                         return F32_LOWER_EQUAL_0 ( d );
00218                 }
00219 
00221 
00222                 T getDistanceTo(const vector3d<T>& point) const
00223                 {
00224                         return point.dotProduct(Normal) + D;
00225                 }
00226 
00228                 vector3d<T> Normal;
00229 
00231                 T D;
00232 };
00233 
00234 
00236 typedef plane3d<f32> plane3df;
00237 
00239 typedef plane3d<s32> plane3di;
00240 
00241 } // end namespace core
00242 } // end namespace irr
00243 
00244 #endif
00245 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Thu May 31 2012 10:57:41 by Doxygen (1.7.6.1)