首页 > 其他分享 >布尔数据 边的相交

布尔数据 边的相交

时间:2023-09-27 21:47:37浏览次数:36  
标签:Real iCnt 重叠 相交 Standard aNbSeg 数据 布尔

布尔数据 边的相交

[email protected]

1 Introduction

在OpenCASCADE中对于边的相交分为三类:边与点,边与边,边与面,边与点的相交已经归结为点与边的相交处理了,边的相交主要处理边与边,边与面的相交。边与边、边与面的相交会引入一个新的数据结构-公共部分Common Part,用于保存重叠的公共部分数据。

2 Edge/Edge Interferences

对于两条边的相交是指在两条边的某些地方的距离小于边的容差之和,主要分为两种情况,一种是两条边只有一个交点的情况;一种是有重叠部分的情况;先看只有一个交点情况:

我们在DRAW中通过脚本构造最简单的情况来测试。

在处理边与边相交的函数BOPAlgo_PaveFiller::PerformEE()中,对每两条边调用BOPAlgo_EdgeEdge进行求交。从这里可以看到Pave Block的使用,相当于对每两条边上的每对Pave Block部分进行求交。这里有一些优化空间,目前是使用的两个循环处理,可以尝试使用BVH来提升一些性能。当每对Pave Block对应的点的索引号一致时,即每对Pave Block的端点重叠时,使用快速计算的算法来判断是否有重叠。

对于边的求交结果保存到BOPDS_InterfEE中,都会保存是哪两条边相交及相交的公共部分。对于相交于一点的公共部分的类型为TopAbs_VERTEX,对于有重叠部分的公共部分类型为TopAbs_EDGE:

当两边条有重叠部分时,如下图所示:

如何检测两条边的公共部分呢?在函数IntTools_EdgeEdge::IsCoincident()中实现:

//=======================================================================
//function :  IsCoincident
//purpose  : 
//=======================================================================
Standard_Boolean IntTools_EdgeEdge::IsCoincident() 
{
  Standard_Integer i, iCnt, aNbSeg, aNbP2;
  Standard_Real dT, aT1, aCoeff, aTresh, aD;
  Standard_Real aT11, aT12, aT21, aT22;
  GeomAPI_ProjectPointOnCurve aProjPC;
  gp_Pnt aP1;
  //
  aTresh=0.5;
  aNbSeg=23;
  myRange1.Range(aT11, aT12);
  myRange2.Range(aT21, aT22);
  //
  aProjPC.Init(myGeom2, aT21, aT22);
  //
  dT=(aT12-aT11)/aNbSeg;
  //
  iCnt=0;
  for(i=0; i <= aNbSeg; ++i) {
    aT1 = aT11+i*dT;
    myGeom1->D0(aT1, aP1);
    //
    aProjPC.Perform(aP1);
    aNbP2=aProjPC.NbPoints();
    if (!aNbP2) {
      continue;
    }
    //
    aD=aProjPC.LowerDistance();
    if(aD < myTol) {
      ++iCnt; 
    }
  }
  //
  aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
  return aCoeff > aTresh;
}

从上述代码可以看出,对于重叠部分的检测是将一条边根据检测范围分成23段采样点,计算每个点到另一条边的距离,满足条件的采样点的数量超过12个,基本认为是重叠的。从这里可以看出这样检测重叠稍微有点不严谨。固定采样点数量对于小段曲线来说数量过大,对于很长的曲线来说数量又偏小,这里有待提高。如果重叠,则将公共部分的数据保存起来:

对于测试的TCL脚本不会走这个通用的判断流程,会直接有IntTools_EdgeEdge::ComputeLineLine()函数来处理这种特殊情况:

从保存的数据可以看出,公共部分的相交类型为TopAbs_VERTEX,及交点分别在两条边上的参数。关于有重叠部分的两条边相交,同学们可以自行使用DRAW脚本来测试一下。

3 Edge/Face Interferences

边与面的相交会遇到和边与边相交类似的情况,即会有重叠部分Common Part。也分为两种情况,一种情况是边与面只有一个交点的情况,交点可能会有多个;一种情况是有重叠部分的情况。

我们可以在使用脚本来测试一下重叠的情况:

从代码中可以看出当边的端点在面上时,则会判断边与面会不会重叠Coincidence。判断逻辑与判断边是否重叠类似,都是使用固定23个采样点的方式处理,并加上定位器来判断点是否在面上,因为面上可能会有孔洞:

//=======================================================================
//function :  IsCoincident
//purpose  : 
//=======================================================================
Standard_Boolean IntTools_EdgeFace::IsCoincident() 
{
  Standard_Integer i, iCnt;
  Standard_Real dT, aT, aD, aT1, aT2, aU, aV;

  gp_Pnt aP;
  TopAbs_State aState;
  gp_Pnt2d aP2d;
  //
  GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace);

  Standard_Integer aNbSeg=23;
  if (myC.GetType() == GeomAbs_Line &&
      myS.GetType() == GeomAbs_Plane)
    aNbSeg = 2; // Check only three points for Line/Plane intersection

  const Standard_Real aTresh = 0.5;
  const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
                         aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
  const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace);

  aT1=myRange.First();
  aT2=myRange.Last();
  Standard_Real aBndShift = 0.01 * (aT2 - aT1);
  //Shifting first and last curve points in order to avoid projection
  //on surface boundary and rejection projection point with minimal distance
  aT1 += aBndShift;
  aT2 -= aBndShift;
  dT=(aT2-aT1)/aNbSeg;
  //
  Standard_Boolean isClassified = Standard_False;
  iCnt=0;
  for(i=0; i <= aNbSeg; ++i) {
    aT = aT1+i*dT;
    aP=myC.Value(aT);
    //
    aProjector.Perform(aP);
    if (!aProjector.IsDone()) {
      continue;
    }
    //
    
    aD=aProjector.LowerDistance();
    if (aD > myCriteria) {
      if (aD > 100. * myCriteria)
        return Standard_False;
      else
        continue;
    }
    //

    ++iCnt; 

    //We classify only three points: in the begin, in the 
    //end and in the middle of the edge.
    //However, exact middle point (when i == (aNbSeg + 1)/2)
    //can be unprojectable. Therefore, it will not be able to
    //be classified. Therefore, points with indexes in 
    //[aTreshIdxF, aTreshIdxL] range are made available 
    //for classification.
    //isClassified == TRUE if MIDDLE point has been chosen and
    //classified correctly.

    if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg)))
      continue;

    if(isClassified && (i != aNbSeg))
      continue;

    aProjector.LowerDistanceParameters(aU, aV);
    aP2d.SetX(aU);
    aP2d.SetY(aV);

    IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace);
    aState = aClass2d.Perform(aP2d);
    
    if(aState == TopAbs_OUT)
      return Standard_False;

    if(i != 0)
      isClassified = Standard_True;
  }
  //
  const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1);
  return (aCoeff > aTresh);
}

求交结果与边与边相交类型,会保存边与面的索引,及公共部分的数据。除了保存这些数据以外,还和点与面相交一样,更新面上的信息FaceInfo,即有哪些边在面上。

4 Conclusion

综上所述,边与边、边与面相交会得到公共部分Common Part,公共部分可能是点,也可能是重叠的边。在过滤相交的边与边、边与面时都有一定的优化空间,即使用BVH来加速检测相交部分。在快速判断边与边是否重叠、边与面是否重叠部分的代码采用固定数量的采样点的处理方式不太严谨。将相交的结果及过程数据都保存到BOPDS_DS中作为后面算法使用。

标签:Real,iCnt,重叠,相交,Standard,aNbSeg,数据,布尔
From: https://www.cnblogs.com/opencascade/p/occt_edge_int.html

相关文章

  • 科技云报道:数据安全合规这门必修课,企业不再缺席
    科技云报道原创。数据作为新型生产要素,占据着国家战略资源地位。然而,层出不穷的数据泄露事件也给数字化转型中的企业带来巨大风险和巨额损失的可能性。据IBM安全发布的《2023年数据泄露成本报告》显示,2023年数据泄露的全球平均成本上升至445万美元,达到历史新高,比2022年的435万美元......
  • go语言ent教程:使用ent定义数据库的表schema、创建表
    背景:在go语言里,常用的与数据库进行交互的包有:gorm、xorm,今天我们讲解的是:ent,本ent系列的教程基于Mac开发环境,归属于go-study项目。 一、准备工作1阅读ent官方的上手教程 https://entgo.io/docs/getting-started2创建测试数据库:test 二、跟着ent官方的上手教程动手......
  • 数据结构学习带背(一)|基本概念
    数据结构的基本概念:数据数据元素数据对象数据类型数据结构数据结构的三要素:1、2、3、分别有什么?===测试可以用()定义一个完整的数据结构(栈是什么?......
  • 面试之关系型数据库
    数据库设计三范式第一范式。任何一张表必须有主键,每一个字段具有原子性不可再分。第二范式。所有非主键字段完全依赖主键字段,不存在部分依赖(复合主键可能存在此情况)。第三范式。所有非主键字段直接依赖于主键字段,不存在传递依赖(比如员工表中存在部门编号和部门名)。注:多......
  • java数据类型拓展
    java数据拓展publicclassdemo3{publicstaticvoidmain(String[]args){//整数拓展:进制二进制0b十进制八进制0十六进制0xinti1=10;inti2=010;inti3=0x10;System.out.println(i1);Syste......
  • Java数据类型
    Java数据类型摘自狂神说java的PPT什么是字节1bit表示一位1Byte表示一个字节1024B=1KB1024KB=1M1024M=1G......
  • 创建指定gbk utf8字符集数据库
    mysql>createdatabasesky9899;QueryOK,1rowaffected(0.00sec)mysql>showdatabases;#显示数据库+--------------------+|Database|+--------------------+|information_schema||db_shop||mysql||oldboy......
  • 数据库的MVCC模式
    PG的mvcc模式:多版本并发控制,通过在数据库中创建多个版本的数据来实现并发的读写操作。每个数据库事务都能够看到一个逻辑上一致的数据库快照,当一个事务修改了数据库中的数据时,他不会直接修改原始数据,而是创建一个新的数据版本,并将修改后的数据写入新的数据版本中,这样其他事务依然......
  • SSIS抽取intersystems cache 数据库数据,SQLSERVER数据库配置CACHE数据库DBLINK
       最近有个新需求,需要用SSIS抽取intersystemscache数据库表数据步骤一:首先想到的是通过ODBC驱动进行连接,第一步安装cache驱动步骤二:配置cache数据库连接串,关键内容:CACHe数据库地址,端口,空间名,用户名,密码步骤三:测试ODBC链接步骤四:SSIS中配置ODBC链接 步骤五:常规数......
  • 最实用的游戏数据辅助器!!!
    游戏辅助器是游戏改变者们的必备工具之一。他们可以帮助玩家更轻松地改变游戏中的各种元素,从而获得更好的游戏体验或优势。这里给大家介绍下好用的游戏辅助器:CheatEngine辅助器是一款用于修改游戏内存和编辑游戏的游戏修改工具。Ce辅助器(CheatEngine)内含十六进制编辑、反汇编、......