00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef __CPLANE_H_
00015 #define __CPLANE_H_
00016
00017 #define ZD_PLANE_INT_COINCIDENT 0
00018 #define ZD_PLANE_INT_ALLIN 1
00019 #define ZD_PLANE_INT_ALLOUT 2
00020 #define ZD_PLANE_INT_OK 3
00021
00022 #define ZD_PLANE_MAX_COORD_X 0
00023 #define ZD_PLANE_MAX_COORD_Y 1
00024 #define ZD_PLANE_MAX_COORD_Z 2
00025
00026
00027 #include "CVector3.h"
00028 #include "CMatrix.h"
00029 #include "Zdef.h"
00030 #include "Zmacro.h"
00031
00033
00035 class CPlane {
00036
00037 public:
00038
00040 zfloat fA,fB,fC,fD;
00041
00043 inline CPlane () {};
00044
00046 inline CPlane (zfloat a, zfloat b, zfloat c, zfloat d) {fA=a; fB=b; fC=c; fD=d;};
00047
00049 inline CPlane (const CVector3 &v1, const CVector3 &v2, const CVector3 &v3) {
00050
00051 CVector3 e;
00052 e.NormUnit(v1,v2,v3);
00053
00054 fA = e.fCoord[0];
00055 fB = e.fCoord[1];
00056 fC = e.fCoord[2];
00057 fD = - (fA*v1.fCoord[0]+fB*v1.fCoord[1]+fC*v1.fCoord[2]);
00058
00059 }
00060
00062
00063 inline CPlane (const CVector3 &v, const CVector3 &n) {
00064
00065 fA = n.fCoord[0];
00066 fB = n.fCoord[1];
00067 fC = n.fCoord[2];
00068 fD = - (fA*v.fCoord[0]+fB*v.fCoord[1]+fC*v.fCoord[2]);
00069
00070 }
00071
00073
00074 inline CPlane (const CPlane &p, zfloat dist) {
00075
00076 fA = p.fA;
00077 fB = p.fB;
00078 fC = p.fC;
00079 fD = p.fD+dist;
00080
00081 }
00082
00084 inline CVector3 Norm () const { return CVector3 (fA,fB,fC);}
00085
00087 inline CVector3 NormUnit () const {
00088
00089 zfloat module = (zfloat) sqrt (fA*fA+fB*fB+fC*fC);
00090 return CVector3 (fA/module, fB/module, fC/module);
00091
00092 }
00093
00095 inline zfloat Dist (const CVector3 &v) const {
00096
00097 return (fA*v.fCoord[0]+fB*v.fCoord[1]+fC*v.fCoord[2]+fD);
00098
00099 }
00100
00102
00103 inline bool IntersectPlanes (const CPlane &P2, const CPlane &P3, CVector3 &inter) const {
00104
00105 CMatrix M ((*this).fA, (*this).fB, (*this).fC, P2.fA, P2.fB, P2.fC, P3.fA, P3.fB, P3.fC);
00106 CMatrix X (-(*this).fD, (*this).fB, (*this).fC, -P2.fD, P2.fB, P2.fC, -P3.fD, P3.fB, P3.fC);
00107 CMatrix Y ((*this).fA, -(*this).fD, (*this).fC, P2.fA, -P2.fD, P2.fC, P3.fA, -P3.fD, P3.fC);
00108 CMatrix Z ((*this).fA, (*this).fB, -(*this).fD, P2.fA, P2.fB, -P2.fD, P3.fA, P3.fB, -P3.fD);
00109
00110 zfloat det = M.determinant3();
00111
00112 if ZM_FLOAT_EQ(det,0) return false;
00113
00114 inter = CVector3 (X.determinant3()/det, Y.determinant3()/det, Z.determinant3()/det);
00115
00116 return true;
00117 }
00118
00120
00130 inline zuint RayIntersection (const CVector3 &v1, const CVector3 &v2,CVector3 &result) const {
00131
00132 zfloat fDist1 = Dist(v1);
00133 zfloat fDist2 = Dist(v2);
00134
00135 if (ZM_FLOAT_EQ(fDist1,0)&&(ZM_FLOAT_EQ(fDist2,0))) {result = v1; return ZD_PLANE_INT_COINCIDENT;}
00136
00137 if ((fDist1 > ZD_EPSILON) && (fDist2 > ZD_EPSILON)) return ZD_PLANE_INT_ALLIN;
00138 if ((fDist1 < -ZD_EPSILON) && (fDist2 < -ZD_EPSILON)) return ZD_PLANE_INT_ALLOUT;
00139
00140 zfloat d = fDist1/(fDist1-fDist2);
00141
00142 result = (v1 + ((v2-v1) * d));
00143
00144 return ZD_PLANE_INT_OK;
00145
00146 }
00147
00149
00150 inline zuint MaxNormCoord () const {
00151
00152 if ((fabs(Norm().fCoord[0]) >= fabs(Norm().fCoord[1])) &&
00153 (fabs(Norm().fCoord[0]) >= fabs(Norm().fCoord[2])))
00154
00155 return ZD_PLANE_MAX_COORD_X;
00156
00157 if ((fabs(Norm().fCoord[1]) >= fabs(Norm().fCoord[0])) &&
00158 (fabs(Norm().fCoord[1]) >= fabs(Norm().fCoord[2])))
00159
00160 return ZD_PLANE_MAX_COORD_Y;
00161
00162 if ((fabs(Norm().fCoord[2]) >= fabs(Norm().fCoord[0])) &&
00163 (fabs(Norm().fCoord[2]) >= fabs(Norm().fCoord[1])))
00164
00165 return ZD_PLANE_MAX_COORD_Z;
00166
00167 return 0;
00168 }
00169
00170
00171 };
00172
00173 #endif