C# CAD多段线等距分割技巧

在C#对CAD进行二次开发时,要将一条多段线(Polyline)等距分割成多份,核心是使用 PolylineGetSplitCurves 方法,并传入一组在曲线参数域内、按升序排列的切割点参数值。

以下是实现将多段线等距分割成10份的完整代码示例:

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

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

        // 1. 选择要分割的多段线 PromptEntityOptions peo = new PromptEntityOptions("
请选择一条多段线: ");
        peo.SetRejectMessage("
请选择一条多段线。");
        peo.AddAllowedClass(typeof(Polyline), false);
        PromptEntityResult per = ed.GetEntity(peo);

        if (per.Status != PromptStatus.OK) return;

        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            try
            {
                // 2. 打开选中的多段线对象
                Polyline pline = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Polyline;
                if (pline == null) return;

                // 3. 计算等距分割点参数
                int numberOfSegments = 10; // 分割成10份 double totalLength = pline.Length;
                double segmentLength = totalLength / numberOfSegments;

                // 准备切割点参数集合,注意必须升序排列
                DoubleCollection splitParams = new DoubleCollection();

                // 从第一个分割点开始,到最后一个分割点前结束
                // 注意:GetSplitCurves方法在参数处切割,起点和终点的参数不需要加入
                for (int i = 1; i < numberOfSegments; i++)
                {
                    double distance = segmentLength * i;
                    // 通过距离获取对应的曲线参数 double param = pline.GetParameterAtDistance(distance);
                    splitParams.Add(param);
                }

                // 4. 执行分割操作
                // 重要:GetSplitCurves 要求参数按升序排列,且不能包含曲线起点和终点的参数
                DBObjectCollection splitCurves = pline.GetSplitCurves(splitParams);

                // 5. 将分割后的新曲线(多段线)添加到模型空间
                BlockTableRecord btr = tr.GetObject(
                    SymbolUtilityServices.GetBlockModelSpaceId(db),
                    OpenMode.ForWrite) as BlockTableRecord;

                foreach (DBObject obj in splitCurves)
                {
                    Entity newEntity = obj as Entity;
                    if (newEntity != null)
                    {
                        btr.AppendEntity(newEntity);
                        tr.AddNewlyCreatedDBObject(newEntity, true);
                    }
                }

                // 6. (可选)删除原始多段线 pline.UpgradeOpen();
                pline.Erase();

                tr.Commit();
                ed.WriteMessage($"
成功将多段线等距分割为 {numberOfSegments} 段。");
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage($"
分割过程中发生错误: {ex.Message}");
                tr.Abort();
            }
        }
    }
}

关键步骤与原理说明:

  1. 获取曲线参数 :多段线的分割基于其内部参数域(通常从0.0到某个最大值)。GetParameterAtDistance 方法用于将沿曲线的长度距离转换为对应的参数值。
  2. 参数排序GetSplitCurves 方法要求传入的切割参数集合 DoubleCollection 必须是严格升序排列的,否则会导致分割失败或结果错误。
  3. 分割点计算 :若要将曲线等分为 N 段,需要在曲线上确定 N-1 个切割点。代码中循环从 i=1i<N,计算每个等分点的距离并转换为参数。
  4. 结果处理GetSplitCurves 返回一个 DBObjectCollection,其中包含了分割后产生的所有新曲线对象。需要将这些新实体添加到数据库(如模型空间)中才能显示。

重要注意事项:

事项 说明
参数范围 不要将曲线起点(参数通常为0.0)和终点的参数加入 splitParams 集合,否则 GetSplitCurves 可能抛出异常或产生意外结果。
对象状态 在事务中,原始多段线在分割前应以 ForRead 模式打开。分割后若需删除原曲线,需先调用 UpgradeOpen() 将其状态改为可写。
分割结果 分割后生成的是多个独立的曲线对象(通常是多个 PolylineLine),它们首尾相连,共同构成原始路径。

参考来源