# eryar

PipeCAD - Plant Piping Design Software.
RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
posts - 581, comments - 590, trackbacks - 0, articles - 0

eryar@163.com

l 一个点

l 一条或两条直线

l 一个点和一条直线

l 圆

l 椭圆

l 抛物线

l 双曲线

```void IntAna_QuadQuadGeo::Perform (const gp_Pln& P1,
const gp_Pln& P2,
const Standard_Real TolAng,
const Standard_Real Tol)
{
Standard_Real A1, B1, C1, D1, A2, B2, C2, D2, dist1, dist2, aMVD;
//
done=Standard_False;
param2bis=0.;
//
P1.Coefficients(A1,B1,C1,D1);
P2.Coefficients(A2,B2,C2,D2);
//
gp_Vec aVN1(A1,B1,C1);
gp_Vec aVN2(A2,B2,C2);
gp_Vec vd(aVN1.Crossed(aVN2));
//
const gp_Pnt& aLocP1=P1.Location();
const gp_Pnt& aLocP2=P2.Location();
//
dist1=A2*aLocP1.X() + B2*aLocP1.Y() + C2*aLocP1.Z() + D2;
dist2=A1*aLocP2.X() + B1*aLocP2.Y() + C1*aLocP2.Z() + D1;
//
aMVD=vd.Magnitude();
if(aMVD <=TolAng) {
// normalles are collinear - planes are same or parallel
typeres = (Abs(dist1) <= Tol && Abs(dist2) <= Tol) ? IntAna_Same
: IntAna_Empty;
}
else {
Standard_Real denom, denom2, ddenom, par1, par2;
Standard_Real X1, Y1, Z1, X2, Y2, Z2, aEps;
//
aEps=1.e-16;
denom=A1*A2 + B1*B2 + C1*C2;
denom2 = denom*denom;
ddenom = 1. - denom2;
denom = ( Abs(ddenom) <= aEps ) ? aEps : ddenom;
par1 = dist1/denom;
par2 = -dist2/denom;
gp_Vec inter1(aVN1.Crossed(vd));
gp_Vec inter2(aVN2.Crossed(vd));
X1=aLocP1.X() + par1*inter1.X();
Y1=aLocP1.Y() + par1*inter1.Y();
Z1=aLocP1.Z() + par1*inter1.Z();
X2=aLocP2.X() + par2*inter2.X();
Y2=aLocP2.Y() + par2*inter2.Y();
Z2=aLocP2.Z() + par2*inter2.Z();
pt1=gp_Pnt((X1+X2)*0.5, (Y1+Y2)*0.5, (Z1+Z2)*0.5);
dir1 = gp_Dir(vd);
typeres = IntAna_Line;
nbint = 1;
//
//-------------------------------------------------------
// When the value of the angle between the planes is small
// the origin of intersection line is computed with error
// [ ~0.0001 ] that can not br considered as small one
// e.g.
// for {A~=2.e-6, dist1=4.2e-5, dist2==1.e-4} =>
// {denom=3.4e-12, par1=12550297.6, par2=32605552.9, etc}
// So,
// the origin should be refined if it is possible
//
Standard_Real aTreshAng, aTreshDist;
//
aTreshAng=2.e-6; // 1.e-4 deg
aTreshDist=1.e-12;
//
if (aMVD < aTreshAng) {
//
aDist1=A1*pt1.X() + B1*pt1.Y() + C1*pt1.Z() + D1;
aDist2=A2*pt1.X() + B2*pt1.Y() + C2*pt1.Z() + D2;
//
Standard_Boolean bIsDone, bIsParallel;
//
// 1.
//
aICQ.Perform(aL1, P1, TolAng, Tol);
bIsDone=aICQ.IsDone();
if (!bIsDone) {
return;
}
//
const gp_Pnt& aPnt1=aICQ.Point(1);
//----------------------------------
// 2.
//
aICQ.Perform(aL2, P2, TolAng, Tol);
bIsDone=aICQ.IsDone();
if (!bIsDone) {
return;
}
//
bIsParallel=aICQ.IsParallel();
if (bIsParallel) {
return;
}
//
const gp_Pnt& aPnt2=aICQ.Point(1);
//
pt1=aPnt2;
}
}
}
done=Standard_True;
}```

l 获取两个平面的一般方程的系数：ABCD，其中平面的法向量（A,B,C)为单位向量；

l 将两个平面的法向量叉乘得到的向量vd为平面交线的方向；

l 分别计算一个平面上的点到另外一个平面的距离：dist1dist2

l 如果向量vd的大小小于指定的精度TolAng，则认为两个平面平行没有交线；如果两个距离dist1dist2小于指定的精度Tol，则认为两个平面是相同的（重合）；

l 计算两个平面的夹角denom

l 根据两个平面的夹角计算交线上的点；

l 后面是处理两个平面夹角很小的情况；

l 最后得到交线上的点pt1和方向dir1

```gp_Pln P3(vd.X(), vd.Y(), vd.Z(), 0.0);
IntAna_Int3Pln aTool(P1, P2, P3);
if (aTool.IsDone())
{
pt1 = aTool.Value();
}```

### Feedback

bool GetIntersection(const gp_Pln&me, const gp_Pln&rhs, gp_Lin&result)
{
if (me.Axis().IsParallel(rhs.Axis(), Precision::Angular()))
{
return false;
}
gp_Ax1 v1 = me.Axis();
gp_Ax1 v2 = rhs.Axis();
gp_Vec lin_dir = v1.Direction().Crossed(v2.Direction());
lin_dir.Normalize();
gp_Vec vv = lin_dir.Crossed(v1.Direction());
vv.Normalize();
gp_Vec u(v1.Location(), v2.Location());
double f = u.Dot(vv);
gp_Vec v = vv * f;
gp_Pnt p0(v1.Location().X() + v.X(), v1.Location().Y() + v.Y(), v1.Location().Z() + v.Z());
gp_Ax1 lin_ax(p0, lin_dir);
result.SetPosition(lin_ax);
return true;
}

 只有注册用户登录后才能发表评论。 【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库 相关文章: