00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 INLINE
00026 CPlane::CPlane()
00027 : FNormal(0.0, 0.0, 0.0), FNormalNorm(0.0), FD(0.0)
00028 {
00029 }
00030
00031 INLINE
00032 CPlane::CPlane(TCoordinate Aa, TCoordinate Ab, TCoordinate Ac, TCoordinate Ad)
00033 {
00034 setPlane(Aa, Ab, Ac, Ad);
00035 }
00036
00037 INLINE
00038 CPlane::CPlane(const CVertex & APoint1,
00039 const CVertex & APoint2,
00040 const CVertex & APoint3)
00041 {
00042 setPlane(APoint1, APoint2, APoint3);
00043 }
00044
00045 INLINE
00046 CPlane::CPlane(const CVertex & ANormal, const CVertex & APoint)
00047 {
00048 setPlane(ANormal, APoint);
00049 }
00050
00051 INLINE
00052 CPlane::~CPlane()
00053 {
00054 }
00055
00056 INLINE
00057 void CPlane::setPlane(TCoordinate Aa, TCoordinate Ab, TCoordinate Ac, TCoordinate Ad)
00058 {
00059 FNormal.setXYZ(Aa, Ab, Ac);
00060 FNormalNorm = FNormal.norm();
00061 FD = Ad;
00062 }
00063
00064 INLINE
00065 void CPlane::setPlane(const CVertex & APoint1,
00066 const CVertex & APoint2,
00067 const CVertex & APoint3)
00068 {
00069 FNormal = (APoint2 - APoint1) * (APoint3 - APoint1);
00070 FNormalNorm = FNormal.norm();
00071 FD = - (APoint1.getX() * FNormal.getX() +
00072 APoint1.getY() * FNormal.getY() +
00073 APoint1.getZ() * FNormal.getZ());
00074 }
00075
00076 INLINE
00077 void CPlane::setPlane(const CVertex & ANormal, const CVertex & APoint)
00078 {
00079 FNormal = ANormal;
00080 FNormalNorm = FNormal.norm();
00081 FD = - (APoint.getX() * FNormal.getX() +
00082 APoint.getY() * FNormal.getY() +
00083 APoint.getZ() * FNormal.getZ());
00084 }
00085
00086 INLINE
00087 const CVertex & CPlane::getNormal() const
00088 {
00089 return FNormal;
00090 }
00091
00092 INLINE
00093 TCoordinate CPlane::getNormalNorm() const
00094 {
00095 return FNormalNorm;
00096 }
00097
00098 INLINE
00099 TCoordinate CPlane::getA() const
00100 {
00101 return FNormal.getX();
00102 }
00103
00104 INLINE
00105 TCoordinate CPlane::getB() const
00106 {
00107 return FNormal.getY();
00108 }
00109
00110 INLINE
00111 TCoordinate CPlane::getC() const
00112 {
00113 return FNormal.getZ();
00114 }
00115
00116 INLINE
00117 TCoordinate CPlane::getD() const
00118 {
00119 return FD;
00120 }
00121
00122 INLINE
00123 void CPlane::reverseOrientation()
00124 {
00125 FNormal = -FNormal;
00126 FD = -FD;
00127 }
00128
00129 INLINE
00130 bool CPlane::isPointOnPlane(const CVertex & APoint) const
00131 {
00132 return isZero(FNormal.getX() * APoint.getX() +
00133 FNormal.getY() * APoint.getY() +
00134 FNormal.getZ() * APoint.getZ() +
00135 FD);
00136 }
00137
00138 INLINE
00139 TCoordinate CPlane::pointDistance(const CVertex & APoint) const
00140 {
00141 return (FNormal.getX() * APoint.getX() +
00142 FNormal.getY() * APoint.getY() +
00143 FNormal.getZ() * APoint.getZ() +
00144 FD) / FNormalNorm;
00145 }
00146
00147 INLINE
00148 bool CPlane::getLineIntersection(const CVertex & APoint,
00149 const CVertex & ADirection,
00150 TCoordinate * AInterParam) const
00151 {
00152 TCoordinate d = FNormal.dot(ADirection);
00153
00154 if (d != 0.0) {
00155 *AInterParam = - (FNormal.dot(APoint) + FD) / d;
00156 }
00157 else
00158 return false;
00159
00160 return true;
00161 }
00162
00163 INLINE
00164 bool CPlane::getLineIntersection(const CVertex & APoint,
00165 const CVertex & ADirection,
00166 CVertex * AInter) const
00167 {
00168 TCoordinate d = FNormal.dot(ADirection);
00169
00170 if (d != 0.0) {
00171 d = - (FNormal.dot(APoint) + FD) / d;
00172 *AInter = APoint + ADirection * d;
00173 }
00174 else
00175 return false;
00176
00177 return true;
00178 }
00179
00180 INLINE
00181 TProjection CPlane::getBestProjection() const
00182 {
00183 if (fabs(FNormal.getZ()) > fabs(FNormal.getX())) {
00184 if (fabs(FNormal.getZ()) > fabs(FNormal.getY()))
00185 return XY_Proj;
00186 else
00187 return XZ_Proj;
00188 }
00189 else {
00190 if (fabs(FNormal.getX()) > fabs(FNormal.getY()))
00191 return YZ_Proj;
00192 else
00193 return XZ_Proj;
00194 }
00195 }
00196
00197 INLINE
00198 CVertex CPlane::projectPoint(const CVertex & APoint) const
00199 {
00200 CVertex pt;
00201 if (getLineIntersection(APoint, getNormal(), &pt))
00202 return pt;
00203 else
00204 return APoint;
00205 }
00206
00207 INLINE
00208 CVertex CPlane::projectPoint(const CVertex & APoint, TProjection AProj) const
00209 {
00210 switch (AProj) {
00211 case XY_Proj:
00212 return CVertex(APoint.getX(), APoint.getY(), 0.0);
00213 case YZ_Proj:
00214 return CVertex(APoint.getY(), APoint.getZ(), 0.0);
00215 case XZ_Proj:
00216 return CVertex(APoint.getX(), APoint.getZ(), 0.0);
00217 }
00218
00219 return APoint;
00220 }
00221
00222 INLINE
00223 CVertex CPlane::unprojectPoint(const CVertex & APoint, TProjection AProj) const
00224 {
00225 switch (AProj) {
00226 case XY_Proj:
00227 assert(FNormal.getZ() != 0.0);
00228 return CVertex(APoint.getX(),
00229 APoint.getY(),
00230 -(APoint.getX() * FNormal.getX() +
00231 APoint.getY() * FNormal.getY() +
00232 FD) / FNormal.getZ());
00233 case YZ_Proj:
00234 assert(FNormal.getX() != 0.0);
00235 return CVertex(-(APoint.getX() * FNormal.getY() +
00236 APoint.getY() * FNormal.getZ() +
00237 FD) / FNormal.getX(),
00238 APoint.getX(),
00239 APoint.getY());
00240 case XZ_Proj:
00241 assert(FNormal.getY() != 0.0);
00242 return CVertex(APoint.getX(),
00243 -(APoint.getX() * FNormal.getX() +
00244 APoint.getY() * FNormal.getZ() +
00245 FD) / FNormal.getY(),
00246 APoint.getY());
00247 }
00248
00249 return APoint;
00250 }
00251