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

参考来源

相关推荐
LccKyI1 小时前
C#学习day05(开发福彩双色球系统附思维导图)
开发语言·学习·c#
-银雾鸢尾-3 小时前
C#中的协变和逆变
开发语言·c#
Chen—LSN5 小时前
C语言——深度理解指针(6)
c语言·开发语言·算法·c#
在世修行17 小时前
从零打造 C# 工业视觉检测系统(八):Modbus RTU 协议解析与 PLC 剔除控制实战
开发语言·c#
花落人散处21 小时前
CDiskClean 开发历程——忽略进程_拖拽功能实现参考
c#
xcLeigh1 天前
Unity基础:C#脚本的创建与挂载——让你的游戏物体活起来
游戏·unity·c#·教程
花落人散处1 天前
CDiskClean 开发历程——文件&进程实时监控-实现方案参考
c#
猿长大人1 天前
C# | MediatR 入门指南:后端架构解耦
分布式·后端·架构·c#·.net
回忆2012初秋1 天前
C# 中的 EAP:基于事件的异步编程全面指南(一)
开发语言·c#
曹牧1 天前
C#:Type
开发语言·c#