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 方法内部会遍历所有线段寻找最近点,性能可接受。若需极高性能,可考虑先对多段线进行离散化采样再计算,但通常无此必要 。
  • 错误处理:实际开发中应增加更完善的异常处理,例如图元非多段线、未闭合等情况。

参考来源

相关推荐
唐青枫5 小时前
别急着拆服务:C#.NET 微服务架构从边界设计到实战
c#·.net
czhc11400756639 小时前
从一份运行日志还原一次生产卡死:三个信号与一场“假卡死“
c#
Jazz_z10 小时前
如何用 C# 读取 Word 中的表格数据
开发语言·c#
阿松爱学习11 小时前
【Unity开发】FileStream 详解及用法指南
unity·c#·unity开发
淡海水13 小时前
12-02-性能-数据结构性能调查案例1-5
数据结构·性能优化·c#
Java的搬运工14 小时前
使用 C# 轻松管理 PDF 文件的用户权限
c#·用户权限
Neil20131 天前
ajax跨域请求
c#
唐青枫1 天前
别把 Razor 当成几段 HTML:C#.NET Razor Pages、MVC 视图与实战详解
c#·.net
专注仿真1 天前
CMO模型文档-活动单元基类
c#·模型·cmo·活动单元基类
我是苏苏1 天前
Agent 开发实战 :C#实现语义检索!向量数据库Qdrant的下载安装及调试步骤
c#·ai编程