C# CAD二次开发找最近点

在 C# CAD 二次开发中,要找到闭合多段线零件 A 上距离鼠标点击点 b' 最近的位置,核心是使用 GetClosestPointTo 方法。以下是实现步骤和关键代码。

1. 获取选择集与图元

首先,通过交互式选择获取用户先后点选的零件 A 和零件 B对应的多段线图元,并记录鼠标在零件 B 上的点击点 b' 的坐标。

csharp 复制代码
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;

[CommandMethod("FindClosestPoint")]
public void FindClosestPoint()
{
    Document doc = Application.DocumentManager.MdiActiveDocument;
    Database db = doc.Database;
    Editor ed = doc.Editor;

    // 第一步:提示用户选择第一个闭合多段线(零件A)
    PromptEntityOptions peoA = new PromptEntityOptions("
请选择第一个闭合多段线(零件A): ");
    peoA.SetRejectMessage("
请选择一个闭合多段线。");
    peoA.AddAllowedClass(typeof(Polyline), true);
    PromptEntityResult perA = ed.GetEntity(peoA);
    if (perA.Status != PromptStatus.OK) return;

    // 第二步:提示用户选择第二个闭合多段线(零件B),并获取鼠标点击点 b'
    PromptEntityOptions peoB = new PromptEntityOptions("
请选择第二个闭合多段线(零件B): ");
    peoB.SetRejectMessage("
请选择一个闭合多段线。");
    peoB.AddAllowedClass(typeof(Polyline), true);
    PromptEntityResult perB = ed.GetEntity(peoB);
    if (perB.Status != PromptStatus.OK) return;
    Point3d clickPointB = perB.PickedPoint; // 鼠标在零件B上的点击位置 b'

    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        // 打开零件A对应的多段线图元 Polyline plineA = tr.GetObject(perA.ObjectId, OpenMode.ForRead) as Polyline;
        if (plineA == null || !plineA.Closed)
        {
            ed.WriteMessage("
零件A不是有效的闭合多段线。");
            return;
        }

        // 核心:计算零件A上距离点 b' 最近的点
        Point3d closestPointOnA = plineA.GetClosestPointTo(clickPointB, false);
        double distance = closestPointOnA.DistanceTo(clickPointB);

        ed.WriteMessage($"
零件A上距离点击点 b' 最近的位置坐标为: ({closestPointOnA.X}, {closestPointOnA.Y})");
        ed.WriteMessage($"
最近距离为: {distance}");

        // (可选)在图中标记出该最近点,便于可视化验证 using (DBPoint marker = new DBPoint(closestPointOnA))
        {
            BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
            btr.AppendEntity(marker);
            tr.AddNewlyCreatedDBObject(marker, true);
        }

        tr.Commit();
    }
}

2. 方法解析与关键点

关键步骤 说明 相关API/概念
交互选择 使用 PromptEntityOptionsEditor.GetEntity 获取用户选择的图元及点击点坐标。 PromptEntityResult.PickedPoint
图元验证 确保选择的对象是 Polyline 类型且为闭合状态 (Closed 属性为 true)。 Polyline.Closed
最近点计算 调用 Polyline.GetClosestPointTo(point, false) 方法。第二个参数 false 表示在无限延伸的曲线上查找(对于闭合多段线,通常设为 false)。 Curve.GetClosestPointTo
距离计算 使用 Point3d.DistanceTo 方法计算最近点与点击点 b' 之间的实际距离。 Point3d.DistanceTo
可视化(可选) 创建 DBPoint 实体并在当前空间追加,以在图中标记出计算出的最近点位置。 DBPoint, BlockTableRecord.AppendEntity

3. 注意事项

  • 图元类型 :上述代码以 Polyline 为例。如果涉及轻量多段线 (LWPolyline),需先转换为 Polyline 或使用其他方法获取其几何边界进行计算 。
  • 坐标系 :确保所有点坐标处于同一坐标系(通常是世界坐标系,WCS)。GetClosestPointTo 方法默认在 WCS 下计算。
  • 性能 :对于非常复杂的多段线(包含大量顶点),GetClosestPointTo 方法内部会遍历所有线段寻找最近点,性能可接受。若需极高性能,可考虑先对多段线进行离散化采样再计算,但通常无此必要 。
  • 错误处理:实际开发中应增加更完善的异常处理,例如图元非多段线、未闭合等情况。

参考来源

相关推荐
fogota5 小时前
【AI】C# .NET8 WPF 第三方DLL引用配置(编译不丢失、不自动删除)
c#·.net·wpf·dll
北域码匠20 小时前
Karatsuba乘法超详细解析(原理+流程+性能分析+纯原生C#无第三方库完整实现)
算法·c#·大数乘法·高精度计算·数据结构与算法·分治算法·karatsuba 乘法
syker1 天前
WinMaster v0.3.3 完整使用手册
c#
Risehuxyc1 天前
C# 将doc转换为docx
开发语言·c#·xhtml
czhc11400756631 天前
717:回调r=>{};norice;fov;pcb;寸动距离;背钻主钻孔;
c#
henreash1 天前
Orleans10的非对称部署(部署更友好的方式)
c#
geovindu1 天前
CSharp: Recursion Algorithm
开发语言·后端·算法·c#·递归算法
geats人山人海1 天前
c# 第八章 多态与案例
开发语言·c#