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

参考来源

相关推荐
棉晗榜1 天前
C# HttpClient配置具有tls指纹发起跟浏览器一样的请求解决反爬虫防护
开发语言·爬虫·c#
吴可可1231 天前
在CAD中点击添加多段线顶点的方法与实现
c#
全栈小51 天前
【C#】.net core,静态方法线程安全解析,面试时经常被问的线程安全就藏在里面
安全·c#·.netcore
天下无敌笨笨熊1 天前
C#视频开发心得
开发语言·c#·音视频
LccKyI1 天前
C#基础编程 面试题汇总(三)
笔记·c#
半亩码田1 天前
C#转Python第4.1篇:当 try-catch 遇上 try-except:异常处理的大不同
开发语言·python·c#
z落落1 天前
C# Modbus-RTU 串口读写设备+CRC16+邮件告警
开发语言·c#
DS随心转小程序1 天前
Gemini只能导出了一部分Word文档,很少的一部分,不是我这个窗口所有的对话内容?
开发语言·人工智能·c#·word·豆包·deepseek·ai导出鸭
格林威1 天前
C# 相机图像配合频闪光源:实现高速稳定拍摄的几个方法
开发语言·网络·人工智能·数码相机·计算机视觉·c#·视觉检测
CSDN_RTKLIB1 天前
CAD绘图单位
c#