291 lines
6.2 KiB
C++
291 lines
6.2 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, SH Software Co. Ltd.
|
|
// = FileName : XPlane 类
|
|
// = Version : ver2.0
|
|
// = Author : zjq
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: XPlane 类定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "XPlane.h"
|
|
#include "XPoint.h"
|
|
#include "XPrivateGlobalFunc.h"
|
|
#include "XGlobalCurveFunc.h"
|
|
#include "XCurveInline.h"
|
|
|
|
XPlane::XPlane()
|
|
: m_dParaA(0.0), m_dParaB(0.0), m_dParaC(1.0), m_dParaD(0.0)
|
|
{
|
|
|
|
}
|
|
|
|
XPlane::XPlane(double aa, double bb, double cc, double dd)
|
|
: m_dParaA(aa), m_dParaB(bb), m_dParaC(cc), m_dParaD(dd)
|
|
{
|
|
|
|
}
|
|
|
|
XPlane::XPlane(const XPlane &src)
|
|
: m_dParaA(src.m_dParaA), m_dParaB(src.m_dParaB),
|
|
m_dParaC(src.m_dParaC), m_dParaD(src.m_dParaD)
|
|
{
|
|
|
|
}
|
|
|
|
XPlane::XPlane(const XPoint &ptOrg, const XVector3D &vtNorm)
|
|
{
|
|
m_dParaA = vtNorm[0];
|
|
m_dParaB = vtNorm[1];
|
|
m_dParaC = vtNorm[2];
|
|
|
|
const XVector3D &vt=vtNorm;
|
|
const XPoint &pt=ptOrg;
|
|
|
|
m_dParaD = 0.0 - (vt[0] * pt[0] + vt[1] * pt[1] + vt[2] * pt[2]);
|
|
}
|
|
|
|
|
|
XPlane::~XPlane()
|
|
{
|
|
|
|
}
|
|
|
|
// 3点确定一平面方程
|
|
BOOL XPlane::SetFrom3p(const XPoint &pt1, const XPoint &pt2, const XPoint &pt3)
|
|
{
|
|
XVector3D vt1 = pt2 - pt1;
|
|
XVector3D vt2 = pt3 - pt1;
|
|
XVector3D vtNorm = vt1 * vt2;
|
|
|
|
if (vtNorm.Length() < 1.0E-9)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
vtNorm.Normalize();
|
|
|
|
m_dParaA = vtNorm[0];
|
|
m_dParaB = vtNorm[1];
|
|
m_dParaC = vtNorm[2];
|
|
|
|
const XVector3D &vt = vtNorm;
|
|
const XPoint &pt = pt1;
|
|
|
|
m_dParaD = 0.0 - (vt[0] * pt[0] + vt[1] * pt[1] + vt[2] * pt[2]);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 平面与线求交,考虑了线是否为无限长
|
|
BOOL XPlane::Intersect(const XLine &ln, XPoint &ptInt) const
|
|
{
|
|
const XPoint &pt1 = ln.GetStartPoint();
|
|
const XPoint &pt2 = ln.GetEndPoint();
|
|
ads_real l, m, n, t;
|
|
ads_real mid_var1, mid_var2;
|
|
|
|
l = pt2[0] - pt1[0];
|
|
m = pt2[1] - pt1[1];
|
|
n = pt2[2] - pt1[2];
|
|
|
|
mid_var1 = l * m_dParaA + m * m_dParaB + n * m_dParaC;
|
|
if (fabs(mid_var1) < 1.0E-9)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
mid_var2 = m_dParaD + pt1[0] * m_dParaA +
|
|
pt1[1] * m_dParaB + pt1[2] * m_dParaC;
|
|
t = 0.0 - mid_var2 / mid_var1;
|
|
|
|
ptInt[0] = pt1[0] + l * t;
|
|
ptInt[1] = pt1[1] + m * t;
|
|
ptInt[2] = pt1[2] + n * t;
|
|
|
|
if (ln.GetLineFlag() != LS_INFINITE)
|
|
{
|
|
int nPrFlag = ptInt & ln;
|
|
if (nPrFlag == PR_OUTSIDE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// 平面与平面求交,求交线(无限长)
|
|
BOOL XPlane::Intersect(const XPlane &plan, XLine &ln) const
|
|
{
|
|
AcGePlane plane1(m_dParaA, m_dParaB,
|
|
m_dParaC, m_dParaD);
|
|
AcGePlane plan2(plan.GetParaA(), plan.GetParaB(), plan.GetParaC(), plan.GetParaD());
|
|
AcGeLine3d ln3d;
|
|
|
|
BOOL bRet = plane1.intersectWith(plan2, ln3d);
|
|
if (bRet)
|
|
{
|
|
AcGeVector3d vt = ln3d.direction();
|
|
|
|
ln.SetLineFlag(LS_INFINITE);
|
|
ln.SetStartPoint(ln3d.pointOnLine());
|
|
ln.SetEndPoint(ln.GetStartPoint() + vt);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
XPlane & XPlane::operator = (const XPlane &src)
|
|
{
|
|
m_dParaA = src.GetParaA();
|
|
m_dParaB = src.GetParaB();
|
|
m_dParaC = src.GetParaC();
|
|
m_dParaD = src.GetParaD();
|
|
|
|
return *this;
|
|
}
|
|
|
|
double XPlane::GetParaA() const
|
|
{
|
|
return m_dParaA;
|
|
}
|
|
|
|
void XPlane::SetParaA(const double dVal)
|
|
{
|
|
m_dParaA = dVal;
|
|
}
|
|
|
|
double XPlane::GetParaB() const
|
|
{
|
|
return m_dParaB;
|
|
}
|
|
|
|
void XPlane::SetParaB(const double dVal)
|
|
{
|
|
m_dParaB = dVal;
|
|
}
|
|
|
|
double XPlane::GetParaC() const
|
|
{
|
|
return m_dParaC;
|
|
}
|
|
|
|
void XPlane::SetParaC(const double dVal)
|
|
{
|
|
m_dParaC = dVal;
|
|
}
|
|
|
|
double XPlane::GetParaD() const
|
|
{
|
|
return m_dParaD;
|
|
}
|
|
|
|
void XPlane::SetParaD(const double dVal)
|
|
{
|
|
m_dParaD = dVal;
|
|
}
|
|
|
|
BOOL XPlane::IsValid() const
|
|
{
|
|
return (XPoint(m_dParaA, m_dParaB, m_dParaC).Length() > 1.0E-9);
|
|
}
|
|
|
|
BOOL XPlane::operator !() const
|
|
{
|
|
return (!IsValid());
|
|
}
|
|
|
|
XVector3D XPlane::GetNormal() const
|
|
{
|
|
XVector3D vt(m_dParaA, m_dParaB, m_dParaC);
|
|
vt.Normalize();
|
|
return vt;
|
|
}
|
|
|
|
double XPlane::GetAngle(XVector3D vtLight)const
|
|
{
|
|
AcGeVector3d vtNormal = GetNormal().AsAcGeVector3d();
|
|
vtLight.Reverse();
|
|
|
|
AcGeVector3d vt = vtLight.AsAcGeVector3d();
|
|
|
|
return vt.angleTo(vtNormal);
|
|
}
|
|
|
|
bool XPlane::IsReflect(XVector3D vtLight)const
|
|
{
|
|
double dAng = GetAngle(vtLight);
|
|
return dAng < PI / 2 - 1E-4;
|
|
}
|
|
|
|
bool XPlane::Reflect(XVector3D vtLight,XVector3D& vtRes)const
|
|
{
|
|
AcGeVector3d vt = vtLight.AsAcGeVector3d();
|
|
vtRes = XVector3D(vt.mirror(GetNormal().AsAcGeVector3d()));
|
|
|
|
return IsReflect(vtLight);
|
|
}
|
|
|
|
bool XPlane::IsKindOf(XEntity::TEntityId entType) const
|
|
{
|
|
switch(entType)
|
|
{
|
|
case XEntity::eEntity:
|
|
case XEntity::ePlane:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
XEntity::TEntityId XPlane::Type() const
|
|
{
|
|
return XEntity::ePlane;
|
|
}
|
|
|
|
void XPlane::CopyFrom(const XEntity* pImpSrc)
|
|
{
|
|
if (this != pImpSrc && pImpSrc->IsKindOf(XEntity::ePlane))
|
|
{
|
|
m_dParaA = ((XPlane*)pImpSrc)->GetParaA();
|
|
m_dParaA = ((XPlane*)pImpSrc)->GetParaB();
|
|
m_dParaA = ((XPlane*)pImpSrc)->GetParaC();
|
|
m_dParaA = ((XPlane*)pImpSrc)->GetParaD();
|
|
}
|
|
}
|
|
|
|
GEOAPI BOOL GetShadowMatrix(const XPlane&plane, const XVector3D &vtLight, AcGeMatrix3d &mShadowMatrix)
|
|
{
|
|
double lightPos[4] = {vtLight[0], vtLight[1], vtLight[2], 0.0f};
|
|
double dot = plane.GetParaA() * lightPos[0]
|
|
+ plane.GetParaB() * lightPos[1]
|
|
+ plane.GetParaC() * lightPos[2]
|
|
+ plane.GetParaD() * lightPos[3];
|
|
if (dot>-1.0E-9)
|
|
{
|
|
return FALSE; //光线平行或同向于平面
|
|
}
|
|
|
|
mShadowMatrix(0,0) = (1.0 - lightPos[0] * plane.GetParaA() / dot);
|
|
mShadowMatrix(0,1) = (-lightPos[0] * plane.GetParaB() / dot);
|
|
mShadowMatrix(0,2) = (-lightPos[0] * plane.GetParaC() / dot);
|
|
mShadowMatrix(0,3) = (-lightPos[0] * plane.GetParaD() / dot);
|
|
|
|
mShadowMatrix(1,0) = (-lightPos[1] * plane.GetParaA() / dot);
|
|
mShadowMatrix(1,1) = (1.0 - lightPos[1] * plane.GetParaB() / dot);
|
|
mShadowMatrix(1,2) = (-lightPos[1] * plane.GetParaC() / dot);
|
|
mShadowMatrix(1,3) = (-lightPos[1] * plane.GetParaD() / dot);
|
|
|
|
mShadowMatrix(2,0) = (-lightPos[2] * plane.GetParaA() / dot);
|
|
mShadowMatrix(2,1) = (-lightPos[2] * plane.GetParaB() / dot);
|
|
mShadowMatrix(2,2) = (1.0 - lightPos[2] * plane.GetParaC() / dot);
|
|
mShadowMatrix(2,3) = (-lightPos[2] * plane.GetParaD() / dot);
|
|
|
|
mShadowMatrix(3,0) = 0.0;
|
|
mShadowMatrix(3,1) = 0.0;
|
|
mShadowMatrix(3,2) = 0.0;
|
|
mShadowMatrix(3,3) = 1.0;
|
|
return TRUE;
|
|
}
|