posts - 414, comments - 576, trackbacks - 0, articles - 0

OpenCASCADE直线与平面求交

Posted on 2019-06-03 16:40 eryar 阅览(220) 谈论(0)  修改 保藏 引证 所属分类: 2.OpenCASCADE

OpenCASCADE直线与平面求交

在《解析几何》相关的书中都给出了直线平和面的一般方程和参数方程。其间直线的一般方程有点向式方式的。

由于过空间一点可作且只能作一条直线平行于已知直线,所以当直线上一点(x0, y0, z0)和它的一方向向量(m,n,p)为已知时,直线就彻底确认了。所以在OpenCASCADE中直线类gp_Lin有一个结构函数:

gp_Lin (const gp_Pnt &P, const gp_Dir &V) 即经过点和方历来结构直线。由直线的点向式方程简单导出直线的参数方程:

其间OpenCASCADE的直线是用参数方程来表明的。

同理关于平面而言,过空间一点能够作并且只能作一平面垂直于一已知直线,所以平面的一点(x0,y0,z0)和它的一个法线方向(A, B, C)为已知时,平面就彻底确认了。所以平面方程也有点向式的:

从一个点和两个不共线的向量确认一个平面作为谈论的起点,能够得出平面的参数方程:

 

如上图所示,已知一个点M0(x0,y0,z0),向量v1(x1,y1,z1)和向量v2(x2,y2,z2),咱们来求点M0和向量V1V2确认的平面方程。点M(x,y,z)在平面上的充要条件是向量M0MV1, V2共面。由于向量V1, V2不平行,所以共面的充要条件是存在仅有的一对实数u, v使:

向量M0MV1V2共面的充要条件是:

依据平面的参数方程可知,要确认一个平面从参数方程的视点来看需求一个点和两个方向。从参数方程推导出一般方程的进程也是核算平面一般方程系数的办法。

依据直线的参数方程及平面的一般方程能够推导出直线与平面交点的核算公式,推导进程如下:

从上面的推导进程能够看出,核算直线与平面的交点首要便是核算参数t,当t求出子孙入直线参数方程即可得到交点坐标。从参数t的核算公式可知,有个特别状况便是分母为零的状况,此刻是直线与平面平行共面需求特别处理。

OpenCASCADE中供给了直线与平面求交的核算类IntAna_IntConicQuad,其完成源码如下:

 

void IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P,
                                   const Standard_Real Tolang,
                                   const Standard_Real Tol,
                                   const Standard_Real Len) {
  // Tolang represente la tolerance angulaire a partir de laquelle on considere
  // que l angle entre 2 vecteurs est nul. On raisonnera sur le cosinus de cet
  // angle, (on a Cos(t) equivalent a t au voisinage de Pi/2).
  
  done=Standard_False;
  Standard_Real A,B,C,D;
  Standard_Real Al,Bl,Cl;
  Standard_Real Dis,Direc;
  P.Coefficients(A,B,C,D);
  gp_Pnt Orig(L.Location());
  L.Direction().Coord(Al,Bl,Cl);
  Direc=A*Al+B*Bl+C*Cl;
  Dis = A*Orig.X() + B*Orig.Y() + C*Orig.Z() + D;
  //
  parallel=Standard_False;
  if (Abs(Direc) < Tolang) {
    parallel=Standard_True;
    if (Len!=0 && Direc!=0) {
      //check the distance from bounding point of the line to the plane
      gp_Pnt aP1, aP2;
      //
      aP1.SetCoord(Orig.X()-Dis*A, Orig.Y()-Dis*B, Orig.Z()-Dis*C);
      aP2.SetCoord(aP1.X()+Len*Al, aP1.Y()+Len*Bl, aP1.Z()+Len*Cl);
      if (P.Distance(aP2) > Tol) {
        parallel=Standard_False;
      } 
    }
  }
  if (parallel) {
    if (Abs(Dis) < Tolang) {
      inquadric=Standard_True;
    }
    else {
      inquadric=Standard_False;
    }
  }
  else {
    parallel=Standard_False;
    inquadric=Standard_False;
    nbpts = 1;
    paramonc [0] = - Dis/Direc;
    pnts[0].SetCoord(Orig.X()+paramonc[0]*Al,
                     Orig.Y()+paramonc[0]*Bl,
                     Orig.Z()+paramonc[0]*Cl);
  }
  done=Standard_True;
}

 

从上述代码中能够看出其核算思路也是先核算参数t,还加了一个特别用法,即当参数Len!=0且参数t的分母!=0时从头判别直线与平面的平行状况。这个用法虽然有平行状况的从头判别,可是假如不平行没有核算交点的处理。所以运用这个函数时,参数Len能够用默认值0,即不必这段处理逻辑。还有个不谨慎的当地是这儿的实数判别没有用区间判别法。