273 lines
5.0 KiB
C++
273 lines
5.0 KiB
C++
//-------------------------------------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TPGePlane 类
|
|
// = Version : ver2.0
|
|
// = Author : wlw
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: TPGePlane 定义
|
|
// = Maintainers:
|
|
//
|
|
//-------------------------------------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TPGePlane.h"
|
|
#include "TGMatrix.h"
|
|
|
|
TPGePlane::TPGePlane()
|
|
: a(x),b(y),c(z)
|
|
{
|
|
|
|
}
|
|
|
|
TPGePlane::TPGePlane(const TGVector3D& vt,const TGPoint& pt)
|
|
: TGVector3D(vt),d(-(vt&pt)),a(x),b(y),c(z)
|
|
{
|
|
}
|
|
|
|
TPGePlane::TPGePlane(const TPGePlane& plane)
|
|
: TGVector3D(plane),d(plane.d),a(x),b(y),c(z)
|
|
{
|
|
}
|
|
|
|
TPGePlane::~TPGePlane()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
TPGePlane& TPGePlane::operator =(const TPGePlane& plane)
|
|
{
|
|
SetNormal(plane);
|
|
d = plane.d;
|
|
return *this;
|
|
}
|
|
|
|
bool TPGePlane::IsValid() const
|
|
{
|
|
return !IsNullVector();
|
|
}
|
|
|
|
void TPGePlane::SetNormal(const TGPoint& vt)
|
|
{
|
|
a = vt.x;
|
|
b = vt.y;
|
|
c = vt.z;
|
|
}
|
|
|
|
void TPGePlane::SetBasePoint(const TGPoint& pt)
|
|
{
|
|
d = -((*this)& pt);
|
|
}
|
|
|
|
TGPoint TPGePlane::GetSamplePoint() const
|
|
{
|
|
if(fabs(a) > fabs(b) && fabs(a) > fabs(c))
|
|
{
|
|
return TGPoint(-d / a,0,0);
|
|
}
|
|
else if(fabs(b) > fabs(c))
|
|
{
|
|
return TGPoint(0,-d / b,0);
|
|
}
|
|
else
|
|
{
|
|
return TGPoint(0,0,-d / c);
|
|
}
|
|
}
|
|
|
|
bool TPGePlane::IsSamePlane(const TPGePlane& plane,bool bSameDirection,bool bNormalized) const
|
|
{
|
|
if(HitTest(plane.GetSamplePoint(),bNormalized).IsNot(GR_IN))
|
|
{
|
|
return false;
|
|
}
|
|
if(bSameDirection)
|
|
{
|
|
return IsSameDirection(plane,bNormalized);
|
|
}
|
|
else
|
|
{
|
|
return IsParallel(plane,bNormalized);
|
|
}
|
|
}
|
|
|
|
bool TPGePlane::Normalize()
|
|
{
|
|
double len = Length();
|
|
if(UP_ZERO(len))
|
|
{
|
|
a /= len;
|
|
b /= len;
|
|
c /= len;
|
|
d /= len;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
GRelation TPGePlane::HitTest(const TGPoint& pt,bool bNormalized) const
|
|
{
|
|
double temp;
|
|
if(bNormalized)
|
|
{
|
|
temp = a * pt.x + b * pt.y + c * pt.z + d;
|
|
}
|
|
else
|
|
{
|
|
double dl = Length();
|
|
temp = (a / dl) * pt.x + (b / dl) * pt.y + (c / dl) * pt.z + d / dl;
|
|
}
|
|
|
|
if(UP_ZERO(temp))
|
|
{
|
|
return GR_UP;
|
|
}
|
|
else if(DOWN_ZERO(temp))
|
|
{
|
|
return GR_DOWN;
|
|
}
|
|
else
|
|
{
|
|
return GR_IN;
|
|
}
|
|
}
|
|
|
|
int TPGePlane::Intersect(const TPGeLine3D& line,double& pa,bool bNormalized) const
|
|
{
|
|
if(bNormalized)
|
|
{
|
|
return LinePlaneInt3D(a,b,c,d,line.basePoint,line,pa);
|
|
}
|
|
|
|
double dl = Length(), dl1 = line.Length();
|
|
TGVector3D vt(line);
|
|
vt /= dl1;
|
|
int iRet = LinePlaneInt3D(a / dl, b / dl, c / dl, d / dl, line.basePoint, vt, pa);
|
|
pa /= dl1;
|
|
return iRet;
|
|
}
|
|
|
|
int TPGePlane::Intersect(const TPGeLine3D& line,TGPoint& pt,bool bNormalized) const
|
|
{
|
|
if(bNormalized)
|
|
{
|
|
return LinePlaneInt3DPt(a,b,c,d,line.basePoint,line,pt);
|
|
}
|
|
double dl = Length();
|
|
TGVector3D vt(line);
|
|
vt.Normalize();
|
|
return LinePlaneInt3DPt(a / dl,b / dl,c / dl,d / dl,line.basePoint,vt,pt);
|
|
}
|
|
|
|
int TPGePlane::Intersect(const TPGePlane& plane,TPGeLine3D& line,bool bNormalized) const
|
|
{
|
|
if(bNormalized)
|
|
{
|
|
return PlaneInt(a,b,c,d,plane.a,plane.b,plane.c,plane.d,line.basePoint,line);
|
|
}
|
|
double dl0 = Length(),dl1 = plane.Length();
|
|
return PlaneInt(a / dl0,b / dl0,c / dl0,d / dl0,plane.a / dl1,plane.b / dl1,plane.c / dl1,plane.d / dl1,line.basePoint,line);
|
|
}
|
|
|
|
void TPGePlane::TransformBy(const TGMatrix* pMat)
|
|
{
|
|
ASSERT(pMat != NULL);
|
|
|
|
TGPoint ptBase = GetSamplePoint();
|
|
pMat->Transform(*this);
|
|
pMat->Transform3D(ptBase);
|
|
SetBasePoint(ptBase);
|
|
}
|
|
|
|
int TPGePlane::LinePlaneInt3D(double A,double B,double C,double D, const TGPoint &pt0,const TGVector3D &vt, double &pa) const
|
|
{
|
|
TGVector3D vt1(A,B,C);
|
|
double n1 = vt1 & vt;
|
|
double n2 = -D - (vt1 & pt0);
|
|
if (EQUAL_ZERO(n1))
|
|
{
|
|
if (EQUAL_ZERO(n2))
|
|
{
|
|
return INT_LINE;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
}
|
|
|
|
pa = n2 / n1;
|
|
return INT_1PT;
|
|
}
|
|
|
|
int TPGePlane::LinePlaneInt3DPt(double A,double B,double C,double D, const TGPoint &pt0,const TGVector3D &vt, TGPoint &pt) const
|
|
{
|
|
TGVector3D vt1(A,B,C);
|
|
double n1 = vt1 & vt;
|
|
double n2 = -D - (vt1 & pt0);
|
|
if (EQUAL_ZERO(n1))
|
|
{
|
|
if (EQUAL_ZERO(n2))
|
|
{
|
|
return INT_LINE;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
}
|
|
|
|
double pa = n2 / n1;
|
|
pt.x = pt0.x + vt.x * pa;
|
|
pt.y = pt0.y + vt.y * pa;
|
|
pt.z = pt0.z + vt.z * pa;
|
|
|
|
return INT_1PT;
|
|
}
|
|
|
|
int TPGePlane::PlaneInt(double A1,double B1,double C1,double D1, double A2,double B2,double C2,double D2, TGPoint &pt,TGVector3D &vt) const
|
|
{
|
|
double A3 = B1 * C2 - C1 * B2,B3 = C1 * A2 - A1 * C2,C3 = A1 * B2 - B1 * A2;
|
|
if (EQUAL_ZERO(A3) && EQUAL_ZERO(B3) && EQUAL_ZERO(C3))
|
|
{
|
|
double temp = A1 * D2 - A2 * D1;
|
|
if (EQUAL_ZERO(temp))
|
|
{
|
|
return INT_PLANE;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
}
|
|
|
|
vt.x = A3;
|
|
vt.y = B3;
|
|
vt.z = C3;
|
|
|
|
if (!EQUAL_ZERO(C3))
|
|
{
|
|
pt.z = 0;
|
|
pt.x = (B1 * D2 - B2 * D1) / C3;
|
|
pt.y = (-A1 * D2 + A2 * D1) / C3;
|
|
}
|
|
else if (!EQUAL_ZERO(B3))
|
|
{
|
|
pt.y = 0;
|
|
pt.x = (-C1 * D2 + C2 * D1) / B3;
|
|
pt.z = (A1 * D2 - A2 * D1) / B3;
|
|
}
|
|
else if (!EQUAL_ZERO(A3))
|
|
{
|
|
pt.x = 0;
|
|
pt.z = (-B1 * D2 + B2 * D1) / A3;
|
|
pt.y = (C1 * D2 - C2 * D1) / A3;
|
|
}
|
|
else
|
|
{
|
|
return INT_NULL;
|
|
}
|
|
|
|
vt.Normalize();
|
|
return INT_LINE;
|
|
}
|