OpenCASCADE圆与平面求交
在 解析几何求交之圆与二次曲面中分析了OpenCASCADE提供的类IntAna_IntConicQuad可以用来计算圆与二次曲面之间的交点,这个算法是将平面Plane作为二次曲面的一个特例来处理,最后主要是对三角函数方程进行求解。
当直接使用圆和平面作为参数时,IntAna_IntConicQuad重载了函数Perform来对圆和平面进行求交计算,这时的算法与前面解三角函数不同,代码如下:
void IntAna_IntConicQuad::Perform (const gp_Circ& C, const gp_Pln& P, const Standard_Real Tolang, const Standard_Real Tol) { done=Standard_False; gp_Pln Plconic(gp_Ax3(C.Position())); IntAna_QuadQuadGeo IntP(Plconic,P,Tolang,Tol); if (!IntP.IsDone()) {return;} if (IntP.TypeInter() == IntAna_Empty) { parallel=Standard_True; Standard_Real distmax = P.Distance(C.Location()) + C.Radius()*Tolang; if (distmax < Tol) { inquadric = Standard_True; } else { inquadric = Standard_False; } done=Standard_True; } else if(IntP.TypeInter() == IntAna_Same) { inquadric = Standard_True; done = Standard_True; } else { inquadric=Standard_False; parallel=Standard_False; gp_Lin Ligsol(IntP.Line(1)); gp_Vec V0(Plconic.Location(),Ligsol.Location()); gp_Vec Axex(Plconic.Position().XDirection()); gp_Vec Axey(Plconic.Position().YDirection()); gp_Pnt2d Orig(Axex.Dot(V0),Axey.Dot(V0)); gp_Vec2d Dire(Axex.Dot(Ligsol.Direction()), Axey.Dot(Ligsol.Direction())); gp_Lin2d Ligs(Orig,Dire); gp_Pnt2d Pnt2dBid(0.0,0.0); gp_Dir2d Dir2dBid(1.0,0.0); gp_Ax2d Ax2dBid(Pnt2dBid,Dir2dBid); gp_Circ2d Cir(Ax2dBid,C.Radius()); IntAna2d_AnaIntersection Int2d(Ligs,Cir); if (!Int2d.IsDone()) {return;} nbpts=Int2d.NbPoints(); for (Standard_Integer i=1; i<=nbpts; i++) { gp_Pnt2d resul(Int2d.Point(i).Value()); Standard_Real X= resul.X(); Standard_Real Y= resul.Y(); pnts[i-1].SetCoord(Plconic.Location().X() + X*Axex.X() + Y*Axey.X(), Plconic.Location().Y() + X*Axex.Y() + Y*Axey.Y(), Plconic.Location().Z() + X*Axex.Z() + Y*Axey.Z()); paramonc[i-1]=Int2d.Point(i).ParamOnSecond(); } done=Standard_True; } }
从上述代码中可以看出,直接对圆和平面求交的算法步骤如下:
l 对圆所在平面与平面进行求交,来判断圆所在平面与平面的状态:平行或是圆在平面内部;
l 如果圆所在平面与平面不平行,则得出交线;
l 然后将交线和圆转换成二维空间进行求交计算;
我觉得在得出圆所在平面与平面的交线后,再转换到二维空间来计算交点的方法有点复杂。在得到两个平面的交线后,就可以直接将圆心P0坐标向交线投影得到垂点Pm,先判断圆心到Pm点距离等于半径时,圆和平面就只有一个交点,就是Pm。小于半径时有两个交点,将Pm沿着交线方向分别移动L和-L距离就可以得到交点了,其中:
这样处理只涉及到一个点向直线投影、一个开方及几个向量操作,代码简单容量理解。