天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 124|回复: 0

曲线和面的交点

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-5-25 11:20:04 | 显示全部楼层 |阅读模式
  1. void findIntersectionWithSpline(AcDbSpline* pSpline, const AcGePlane& plane)
  2. {
  3.     if (!pSpline)
  4.         return;
  5.     // 获取Spline的几何表示
  6.     AcGeSplineCurve3d splineGeom;
  7.     pSpline->getSplineGeometry(splineGeom);
  8.     // 交点数组
  9.     AcGePoint3dArray intersectionPts;
  10.     // 交点查找逻辑可能需要根据具体需求实现,这里提供一个简化的思路
  11.     double paramStart = splineGeom.startParameter();
  12.     double paramEnd = splineGeom.endParameter();
  13.     double tol = 1e-6; // 容差值,根据需要调整
  14.     // 数值方法求解交点,这里简化处理,实际情况可能需要更精细的迭代
  15.     for(double t = paramStart; t <= paramEnd; t += (paramEnd - paramStart) / 100.0) // 简单分段处理
  16.     {
  17.         AcGePoint3d pt = splineGeom.evalPoint(t);
  18.         if (plane.normal().isParallelTo(pt - plane.origin()) == Adesk::kFalse) // 判断点是否大致位于平面上
  19.         {
  20.             // 进一步检查点是否确实在平面上(考虑容差)
  21.             if (plane.distanceTo(pt) <= tol)
  22.             {
  23.                 intersectionPts.append(pt);
  24.             }
  25.         }
  26.     }
  27.     // 处理交点数组intersectionPts
  28.     // ...
  29. }
  30. static void findIntersectionByDichotomy(AcDbCurve* pCurve, const AcGePlane& plane, double tol = 1e-7)
  31. {
  32.         if (!pCurve)
  33.                 return;
  34.         // 获取Spline的几何表示
  35.        
  36.         double paramStart;
  37.         pCurve->getStartParam(paramStart);
  38.        
  39.        
  40.         double paramEnd ;
  41.         pCurve->getEndParam(paramEnd);
  42.         double midParam;
  43.         while ((paramEnd - paramStart) > tol)
  44.         {
  45.                 midParam = (paramStart + paramEnd) / 2.0;
  46.                 // 计算中点位置
  47.                 AcGePoint3d midPoint;
  48.                 pCurve->getPointAtParam(midParam,midPoint);
  49.        
  50.                 // 判断中点与平面的相对位置,调整搜索区间
  51.                 double distToPlane = plane.distanceTo(midPoint);
  52.                 if (distToPlane < tol)
  53.                 {
  54.                         // 点在平面上,记录交点并继续在两侧查找可能的其他交点
  55.                         // 注意:这里直接记录了交点,实际应用中可能需要进一步逻辑处理连续交点的情况
  56.                         // midPoint即为一交点
  57.                         paramStart = midParam; // 继续在左侧搜索
  58.                         paramEnd = midParam; // 也在右侧搜索
  59.                 }
  60.                 else {
  61.                         // 使用向量点积判断方向,但需注意,这里逻辑需要明确化
  62.                         AcGePoint3d staPoint,endPoint;
  63.                         pCurve->getStartPoint(staPoint);
  64.                         pCurve->getEndPoint(staPoint);
  65.                         AcGeVector3d startVec = midPoint - staPoint;
  66.                         AcGeVector3d endVec = midPoint - endPoint;
  67.                         double dotStart = plane.normal().dotProduct(startVec);
  68.                         double dotEnd = plane.normal().dotProduct(endVec);
  69.                         // 如果一个点在平面上方,一个在下方,说明交点在区间内
  70.                         if ((dotStart * dotEnd) < 0) {
  71.                                 paramEnd = midParam; // 缩小区间在左侧
  72.                         } else {
  73.                                 paramStart = midParam; // 缩小区间在右侧
  74.                         }
  75.                 }
  76.         }
  77. }
  78. static void findIntersectionWithSpline(AcDbCurve* pCurve, const AcGePlane& plane)
  79. {
  80.         if (!pCurve)
  81.                 return;
  82.         // 获取Spline的几何表示
  83.         double paramStart;
  84.         pCurve->getStartParam(paramStart);
  85.         double paramEnd ;
  86.         pCurve->getEndParam(paramEnd);
  87.         // 交点数组
  88.         AcGePoint3dArray intersectionPts;
  89.         double tol = 1e-6; // 容差值,根据需要调整
  90.         // 主循环,遍历初始参数区间
  91.         while (paramStart <= paramEnd)
  92.         {
  93.                 // 简单分段处理,初步查找交点候选
  94.                 for(double t = paramStart; t <= paramEnd; t += (paramEnd - paramStart) / 100.0)
  95.                 {
  96.                         AcGePoint3d pt ;
  97.             pCurve->getPointAtParam(t,pt);
  98.                         // 判断点是否接近平面上
  99.                         if (std::abs(plane.distanceTo(pt)) <= tol)
  100.                         {
  101.                                 intersectionPts.append(pt);
  102.                                 // 一旦发现交点,锁定当前区间两端点,进行更细粒度的搜索
  103.                                 double newParamStart = max(paramStart, t - (paramEnd - paramStart) / 100.0);
  104.                                 double newParamEnd =   min(paramEnd, t + (paramEnd - paramStart) / 100.0);
  105.                                 // 递归细分并查找该区间内的交点
  106.                                 findIntersectionSubdivided(pCurve, plane, newParamStart, newParamEnd, tol, intersectionPts);
  107.                                 // 发现交点后,移动start参数避免重复查找
  108.                                 paramStart = newParamEnd;
  109.                                 // 退出循环,避免在当前粗略区间重复检查
  110.                                 break;
  111.                         }
  112.                 }
  113.                 // 缩小搜索区间,避免已查找到的交点区间重复检查
  114.                 paramEnd = paramStart;
  115.         }
  116. }
  117. // 辅助函数,用于递归细分区间查找交点
  118. static void findIntersectionSubdivided(const AcDbCurve *splineGeom, const AcGePlane& plane, double startParam, double endParam, double tol, AcGePoint3dArray& intersectionPts)
  119. {
  120.         if (endParam - startParam <= tol)
  121.                 return;
  122.         for(double t = startParam; t <= endParam; t += (endParam - startParam) / 100.0)
  123.         {
  124.                  
  125.                 AcGePoint3d pt ;
  126.                 splineGeom->getPointAtParam(t,pt);
  127.                 if (std::abs(plane.distanceTo(pt)) <= tol)
  128.                 {
  129.                         intersectionPts.append(pt);
  130.                         // 继续细分找到的交点周围区域
  131.                         findIntersectionSubdivided(splineGeom, plane, max(startParam, t - (endParam - startParam) / 100.0), min(endParam, t + (endParam - startParam) / 100.0), tol, intersectionPts);
  132.                         break;
  133.                 }
  134.         }
  135. }
  136. static void findIntersectionByDichotomy(AcDbCurve* pCurve, const AcGePlane& plane, double tol = 1e-7)
  137. {
  138.         if (!pCurve)
  139.                 return;
  140.         // 获取Spline的几何表示
  141.        
  142.         double paramStart;
  143.         pCurve->getStartParam(paramStart);
  144.        
  145.        
  146.         double paramEnd ;
  147.         pCurve->getEndParam(paramEnd);
  148.         double midParam;
  149.         while ((paramEnd - paramStart) > tol)
  150.         {
  151.                 midParam = (paramStart + paramEnd) / 2.0;
  152.                 // 计算中点位置
  153.                 AcGePoint3d midPoint;
  154.                 pCurve->getPointAtParam(midParam,midPoint);
  155.        
  156.                 // 判断中点与平面的相对位置,调整搜索区间
  157.                 double distToPlane = plane.distanceTo(midPoint);
  158.                 if (distToPlane < tol)
  159.                 {
  160.                         // 点在平面上,记录交点并继续在两侧查找可能的其他交点
  161.                         // 注意:这里直接记录了交点,实际应用中可能需要进一步逻辑处理连续交点的情况
  162.                         // midPoint即为一交点
  163.                         paramStart = midParam; // 继续在左侧搜索
  164.                         paramEnd = midParam; // 也在右侧搜索
  165.                 }
  166.                 else {
  167.                         // 使用向量点积判断方向,但需注意,这里逻辑需要明确化
  168.                         AcGePoint3d staPoint,endPoint;
  169.                         pCurve->getStartPoint(staPoint);
  170.                         pCurve->getEndPoint(staPoint);
  171.                         AcGeVector3d startVec = midPoint - staPoint;
  172.                         AcGeVector3d endVec = midPoint - endPoint;
  173.                         double dotStart = plane.normal().dotProduct(startVec);
  174.                         double dotEnd = plane.normal().dotProduct(endVec);
  175.                         // 如果一个点在平面上方,一个在下方,说明交点在区间内
  176.                         if ((dotStart * dotEnd) < 0) {
  177.                                 paramEnd = midParam; // 缩小区间在左侧
  178.                         } else {
  179.                                 paramStart = midParam; // 缩小区间在右侧
  180.                         }
  181.                 }
  182.         }
  183. }
复制代码

 

 

 

 

曲线和面的交点
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-5 12:34 , Processed in 0.123024 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表