明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1275|回复: 9

判断点是否在曲线上

  [复制链接]
发表于 2025-9-2 22:09:40 | 显示全部楼层 |阅读模式


直线、多段线(1d 2d 3d)、圆弧、圆、椭圆弧、样条曲线


AutoCAD 2013 版本以上直接用
es = acdbConvertAcDbCurveToGelibCurve(pCurve, pGeCurve);
// 或者用 getAcGeCurve
// es = pCurve->getAcGeCurve(pGeCurve);
AcGeCurve3d::isOn

AutoCAD 2013 版本以下需要构造 AcGe 类,然后用
static_cast<AcGeCurve3d*>(pGeLine->copy())

至于曲线转换类高大侠分享过。


  1. Acad::ErrorStatus es;
  2. ads_name name;
  3. AcGePoint3d pt;
  4. if (acedEntSel(_T("\n请选择一条曲线:"), name, asDblArray(pt)) != RTNORM)
  5.     return;

  6. AcDbObjectId objId;
  7. es = acdbGetObjectId(objId, name);
  8. if (es != Acad::eOk) return;
  9. AcDbEntity *pEnt = NULL;
  10. es = acdbOpenObject(pEnt, objId, AcDb::kForRead);
  11. if (es != Acad::eOk) return;

  12. AcGeCurve3d* pGeCurve = NULL;

  13. #if _MSC_VER > 1500
  14. if (pEnt->isKindOf(AcDbCurve::desc()))
  15. {
  16.     AcDbCurve *pCurve = AcDbCurve::cast(pEnt);
  17.     // 转换为几何类
  18.     es = acdbConvertAcDbCurveToGelibCurve(pCurve, pGeCurve);
  19.     // 或者用 getAcGeCurve
  20.     // es = pCurve->getAcGeCurve(pGeCurve);
  21.     pCurve->close();
  22. }
  23. #else   // 低于 AutoCAD 2013 版本
  24. if (pEnt->isKindOf(AcDbLine::desc()))
  25. {
  26.     AcDbLine *pLine = AcDbLine::cast(pEnt);
  27.     AcGeLineSeg3d* pGeLine = CCurveConversion::AcDbCurveToAcGeCurve(pLine);
  28.     pGeCurve = static_cast<AcGeCurve3d*>(pGeLine->copy());
  29.     pLine->close();
  30. }
  31. else if (pEnt->isKindOf(AcDbPolyline::desc()))
  32. {
  33.     AcDbPolyline *pPoly = AcDbPolyline::cast(pEnt);
  34.     AcGeCompositeCurve3d* pGePoly = CCurveConversion::AcDbCurveToAcGeCurve(pPoly);
  35.     pGeCurve = static_cast<AcGeCurve3d*>(pGePoly->copy());
  36.     pPoly->close();
  37. }
  38. else if (pEnt->isKindOf(AcDb2dPolyline::desc()))
  39. {
  40.     AcDb2dPolyline *pPoly = AcDb2dPolyline::cast(pEnt);
  41.     AcGeCompositeCurve3d* pGePoly = CCurveConversion::AcDbCurveToAcGeCurve(pPoly);
  42.     pGeCurve = static_cast<AcGeCurve3d*>(pGePoly->copy());
  43.     pPoly->close();
  44. }
  45. else if (pEnt->isKindOf(AcDb3dPolyline::desc()))
  46. {
  47.     AcDb3dPolyline *pPoly = AcDb3dPolyline::cast(pEnt);
  48.     AcGeCompositeCurve3d* pGePoly = CCurveConversion::AcDbCurveToAcGeCurve(pPoly);
  49.     pGeCurve = static_cast<AcGeCurve3d*>(pGePoly->copy());
  50.     pPoly->close();
  51. }
  52. else if (pEnt->isKindOf(AcDbArc::desc()))
  53. {
  54.     AcDbArc *pArc = AcDbArc::cast(pEnt);
  55.     AcGeCircArc3d* pGeArc = CCurveConversion::AcDbCurveToAcGeCurve(pArc);
  56.     pGeCurve = static_cast<AcGeCurve3d*>(pGeArc->copy());
  57.     pArc->close();
  58. }
  59. else if (pEnt->isKindOf(AcDbCircle::desc()))
  60. {
  61.     AcDbCircle *pCircle = AcDbCircle::cast(pEnt);
  62.     AcGeCircArc3d* pGeCircle = CCurveConversion::AcDbCurveToAcGeCurve(pCircle);
  63.     pGeCurve = static_cast<AcGeCurve3d*>(pGeCircle->copy());
  64.     pCircle->close();
  65. }
  66. else if (pEnt->isKindOf(AcDbEllipse::desc()))
  67. {
  68.     AcDbEllipse *pEllipse = AcDbEllipse::cast(pEnt);
  69.     AcGeCircArc3d* pGeEllipse = CCurveConversion::AcDbCurveToAcGeCurve(pEllipse);
  70.     pGeCurve = static_cast<AcGeCurve3d*>(pGeEllipse->copy());
  71.     pEllipse->close();
  72. }
  73. else if (pEnt->isKindOf(AcDbSpline::desc()))
  74. {
  75.     AcDbSpline *pSpline = AcDbSpline::cast(pEnt);
  76.     AcGeCircArc3d* pGeSpline = CCurveConversion::AcDbCurveToAcGeCurve(pSpline);
  77.     pGeCurve = static_cast<AcGeCurve3d*>(pGeSpline->copy());
  78.     pSpline->close();
  79. }
  80. #endif
  81. if (pGeCurve)
  82. {
  83.     // 设置捕捉
  84.     resbuf rb;
  85.     rb.rbnext = NULL;
  86.     rb.restype = RTSHORT;
  87.     rb.resval.rint = 555;
  88.     acedSetVar(_T("osmode"), &rb);

  89.     AcGePoint3d ptTest;
  90.     while (acedGetPoint(NULL, _T("\n请拾取点测试是否在曲线上:"), asDblArray(ptTest)) == RTNORM)
  91.     {
  92.         // 拾取点是否位于曲线上
  93.         if (pGeCurve->isOn(ptTest))
  94.             acutPrintf(_T("\n点在曲线上"));
  95.         else
  96.             acutPrintf(_T("\n点不在曲线上"));
  97.     }

  98.     rb.resval.rint = 0;
  99.     acedSetVar(_T("osmode"), &rb);

  100.     delete pGeCurve;
  101. }

  102. pEnt->close();



回复

使用道具 举报

发表于 2025-9-2 22:59:00 | 显示全部楼层
可能需要增加容差
支持容差判断(考虑浮点精度)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-2 23:00:04 | 显示全部楼层
GE_DLLEXPIMPORT Adesk::Boolean isOn(
    const AcGePoint3d& pnt,
    const AcGeTol& tol = AcGeContext::gTol
) const;

第二个参数
回复 支持 反对

使用道具 举报

发表于 2025-9-3 08:10:05 | 显示全部楼层
求点到线的最近点, 在计算这两点距离
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-3 09:47:17 | 显示全部楼层
本帖最后由 gzxl 于 2025-9-3 10:07 编辑
asen 发表于 2025-9-3 08:10
求点到线的最近点, 在计算这两点距离

多种方法可以比较。
回复 支持 反对

使用道具 举报

发表于 2025-9-3 21:19:26 | 显示全部楼层
曲线转换类 能否在提供?谢谢!!
回复 支持 反对

使用道具 举报

发表于 2025-9-4 04:38:22 | 显示全部楼层
  1.         // 获取点到曲线最近点并判断是否在曲线上
  2.         static void GetClosestPointOnCurve()
  3.         {
  4.                 ads_name ename; // 实体选择结果
  5.                 AcGePoint3d ptPick; // 选择点坐标

  6.                 // 选择曲线实体
  7.                 if (acedEntSel(_T("\n请选择一条曲线:"), ename, asDblArray(ptPick)) != RTNORM)
  8.                         return;

  9.                 AcDbObjectId objId; // 实体对象ID
  10.                 Acad::ErrorStatus es = acdbGetObjectId(objId, ename); // 获取对象ID
  11.                 if (es != Acad::eOk) return;

  12.                 AcDbEntity* pEnt = NULL; // 实体指针
  13.                 es = acdbOpenObject(pEnt, objId, AcDb::kForRead); // 以只读方式打开实体
  14.                 if (es != Acad::eOk) return;

  15.                 // 检查是否为曲线类型
  16.                 if (pEnt->isKindOf(AcDbCurve::desc()))
  17.                 {
  18.                         AcDbCurve* pCurve = AcDbCurve::cast(pEnt); // 转换为曲线对象
  19.                         if (pCurve != NULL)
  20.                         {
  21.                                 AcGePoint3d ptTest; // 测试点坐标

  22.                                 // 循环获取测试点
  23.                                 while (acedGetPoint(NULL, _T("\n请拾取点测试是否在曲线上:"), asDblArray(ptTest)) == RTNORM)
  24.                                 {
  25.                                         AcGePoint3d ptNearest; // 最近点坐标

  26.                                         // 获取曲线上最近点
  27.                                         if (pCurve->getClosestPointTo(ptTest, ptNearest) == Acad::eOk)
  28.                                         {
  29.                                                 // 计算距离判断是否在曲线上
  30.                                                 double dDist = ptTest.distanceTo(ptNearest);
  31.                                                 if (dDist < 1e-7)
  32.                                                         acutPrintf(_T("\n点在曲线上"));
  33.                                                 else
  34.                                                         acutPrintf(_T("\n点不在曲线上,最近距离: %f"), dDist);
  35.                                         }
  36.                                         else
  37.                                         {
  38.                                                 acutPrintf(_T("\n获取最近点失败"));
  39.                                         }
  40.                                 }

  41.                                 pCurve->close(); // 关闭曲线对象
  42.                         }
  43.                 }

  44.                 pEnt->close(); // 关闭实体对象
  45.         }
复制代码

评分

参与人数 1明经币 +1 收起 理由
gzxl + 1 很给力!

查看全部评分

回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-4 06:43:18 | 显示全部楼层
本帖最后由 gzxl 于 2025-9-4 06:45 编辑

在曲线某些方面 AcGe 比 AcDb 好用又快,比如这个求自相交点

http://www.mjtd.com/home.php?mod ... do=blog&id=16373329
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-9-4 23:15:29 | 显示全部楼层
lhg 发表于 2025-9-3 21:19
曲线转换类 能否在提供?谢谢!!

https://www.cnblogs.com/mjgw/p/12459597.html
回复 支持 反对

使用道具 举报

发表于 2025-9-5 20:51:40 | 显示全部楼层
谢谢了谢谢了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-10-6 01:45 , Processed in 0.173014 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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