stmoong 发表于 2022-7-6 22:55:00

使用GetSplitCurves(点

我试图使用GetSplitCurves(Point3dCollection)方法将多边形分割为3个独立的部分。
 
原始多边形如下所示。它是一个多段线对象,是闭合的。

 
我传入Point3dCollection,它由点A、B、C和D按顺序组成。当我检查返回实体的顶点时,我得到2个多边形,而不是3个,并且顶点的顺序不正确:

 
我可以知道是否可以通过4个坐标,这样当多边形被分割时,我们得到3个多边形-中心多边形将是A,B,C,D,其他两个多边形将是两侧吗?
 
 
以下是我的代码片段:

List<custom_object> myPolygons = new List<custom_object>();

DBObjectCollection acDboCol = acPoly.GetSplitCurves(acPt3dCol);
foreach (Entity acEnt in acDboCol)
{
   Polyline acNewPLine = acEnt as Polyline;
   acNewPLine.Closed = true;

   List<Point3d> acVertices = new List<Point3d>();

   for (int i = 0; i < acNewPLine.NumberOfVertices; i++)
   {
       acVertices.Add(acNewPLine.GetPoint3dAt(i));
   }

   myPolygons.Add(acVertices);
   acNewPLine.Dispose();
}

// Dispose of DBObject derived types
acPoly.Dispose();
acDboCol.Dispose();

SEANT 发表于 2022-7-6 23:01:16

是否可以隔离裂缝?仅将点A和B添加到acPt3dCol、GetSplitCurves,关闭acDboCol中的每个实体。
然后
清除acPt3dCol并在acDboCol中的曲线上添加C&D、GetSplitCurves等。
一个问题是,从第一次迭代开始,C&D将只落在两个闭合多边形中的一个上。除非主要关注速度优化,否则这可能不是问题。

stmoong 发表于 2022-7-6 23:08:46

是的,我也试过那个方法,结果很奇怪。
 
我只是想澄清一下,所有这些都是作为背景计算完成的,即应用程序实际上并没有绘制实体,多段线实例纯粹用于获取分割多边形的顶点。
 
 

我调用GetSplitCurves,传入3dPointCollection(由A、B组成)。在循环中,我将实体转换为多段线,并将闭合设置为true。
 
在主循环的第一次迭代中,我调用另一个GetSplitCurves on Polyline(A,2,3,B),传入3dPointCollection(由C,D组成)。
 
在我的例子中,它抛出了一个Autodesk。AutoCAD。运行时。ErrorStatus==InvalidInput异常,因此我忽略它,只存储结果,因为这似乎是我尝试将多段线与外部的另一条多段线拆分的情况。
 
 
然后,在第二次迭代中,使用3dPointCollection(由C、D组成)对多段线(A、B、4、1)调用GetSplitCurves方法,返回1个具有8个顶点的实体。该图元是具有顶点顺序(D、4、1、a、B、4、1、C)的多段线。

我不确定这是因为双重数据类型,还是因为我需要保存数据库事务或其他什么?我用Line2d的方法得到了这些交点。GetPerpendicularLine(),传入B和D作为输入参数,得到相应的A和C,并将其存储在Point3dCollection中。

SEANT 发表于 2022-7-6 23:14:58

以下是作为“隔离拆分”示例修改的测试代码(来自上一个线程)。它确实需要一个复杂的循环结构,以确保一切都在适当的时间发生。这似乎是可行的,尽管这套程序经受住了很少的测试。
 
关于数据库服务。曲线几何。曲线2D/3d,上面的例程与边距不谋而合。在我看来,任何比这更复杂的几何操作都有利于几何名称空间。
 
编辑:删除错误代码!

stmoong 发表于 2022-7-6 23:19:13

这是我之前测试的代码片段。看起来很像。
 
我猜我需要以某种方式重新排列分割多边形的第一段,以便第二条分割多段线的起点位于该段上。我可能错了,但在我看来,GetSplitCurves()算法是按顺时针顺序进行的,然后分割多边形。
 
仍在研究重新排序算法。丑陋的代码,一旦我让它工作,将不得不重构。
 
我曾想过使用几何体名称空间,但不知道如何获得分割的多边形。这可能会导致代码更简洁。
 

         List<MyCustomObject> myCustomObjList = new List<MyCustomObject>();
         DBObjectCollection acDboCol_1 = null;
         try
         {
               acDboCol_1 = acPoly.GetSplitCurves(acPt3dCol_1);
               foreach (Entity acEnt in acDboCol_1)
               {
                   Polyline acNewPLine = acEnt as Polyline;
                   acNewPLine.Closed = true;

                   DBObjectCollection acDboCol_2 = null;
                   try
                   {
                     acDboCol_2 = acNewPLine.GetSplitCurves(acPt3dCol_2);
                     foreach (Entity acEnt2 in acDboCol_2)
                     {
                           Polyline acNewPLine2 = acEnt2 as Polyline;
                           acNewPLine2.Closed = true;

                           MyCustomObject myCustomObj = new MyCustomObject();
                           myCustomObj.Vertices = new List<Point3d>();

                           for (int i = 0; i < acNewPLine2.NumberOfVertices; i++)
                           {
                               myCustomObj.Vertices.Add(acNewPLine2.GetPoint3dAt(i));
                           }
                           myCustomObjList.Add(myCustomObj);
                           acNewPLine2.Dispose();
                     }
                   }
                   catch (Autodesk.AutoCAD.Runtime.Exception ex)
                   {
                     if (ex.ErrorStatus == Autodesk.AutoCAD.Runtime.ErrorStatus.InvalidInput)
                     {
                           MyCustomObject myCustomObj = new MyCustomObject();
                           myCustomObj.Vertices = new List<Point3d>();

                           for (int i = 0; i < acNewPLine2.NumberOfVertices; i++)
                           {
                               myCustomObj.Vertices.Add(acNewPLine2.GetPoint3dAt(i));
                           }
                           myCustomObjList.Add(myCustomObj);

                     }
                     else
                     {
                           // Throw out other exceptions
                           throw ex;
                     }
                   }
                   finally
                   {
                     acNewPLine.Dispose();
                     if (acDboCol_2 != null)
                           acDboCol_2.Dispose();
                   }
               }
         }
         finally
         {
               if (acDboCol_1 != null)
                   acDboCol_1.Dispose();
         }

SEANT 发表于 2022-7-6 23:28:52

一切看起来都很好。“MyCustomObject”中发生了什么?MyCustomObject to数据库中是否存在问题。多段线过程?
 
需要考虑的一件事;图形编辑器中有两种类型的多段线,可以显示相同的多段线。例如,根据多段线闭合的方式和时间,一个可以有四个顶点,而另一个可以有五个顶点。见附件。
多示例。图纸

stmoong 发表于 2022-7-6 23:32:00

“MyCustomObject”只是一个业务对象,它使用一个通用列表来保存当前的顶点列表。
 
关于“PolyExample.dwg”,我看不出有什么不同,有没有检查顶点数量的命令?(除了编写代码和显示)
 
 
我测试了排序代码。它适用于我当前的测试数据集。根据传入顶点的顺序,可能需要在第一次分割时执行此操作。我注意到每次拆分时,其中一条拆分的多段线的顺序都是“错误的”。
 
 

         List<MyCustomObject> myCustomObjList = new List<MyCustomObject>();
         DBObjectCollection acDboCol_1 = null;
         try
         {
               acDboCol_1 = acPoly.GetSplitCurves(acPt3dCol_1);
               foreach (Entity acEnt in acDboCol_1)
               {
                   Polyline acNewPLine = acEnt as Polyline;
                   acNewPLine.Closed = true;

                   // Sort the polyline so that the starting point for the second split-line lies on the first segment of the polyline.
                   // This is required because the splitting will give strange result when attempt to split a polyline where the first segment does not
                   // contain the start point of the split line...
                   for (int i = 0; i < acNewPLine.NumberOfVertices; i++)
                   {
                     LineSegment3d acTmpLine = acNewPLine.GetLineSegmentAt(i);
                     if (acTmpLine.IsOn(acPt3dCol2Start))
                     {
                           // Sort if it's not on the first segment
                           if (acNewPLine.StartPoint != acTmpLine.StartPoint)
                           {
                               List<Point3d> acTmpPts = new List<Point3d>();
                               for (int j = i; j < acNewPLine.NumberOfVertices; j++)
                               {
                                 acTmpPts.Add(acNewPLine.GetPoint3dAt(j));
                               }

                               for (int j = 0; j < i; j++)
                               {
                                 acTmpPts.Add(acNewPLine.GetPoint3dAt(j));
                               }

                               acNewPLine.Reset(false, 0); // clear all the existing vertices
                               foreach (Point3d acTmpPt in acTmpPts)
                               {
                                 // Add to the last position
                                 acNewPLine.AddVertexAt(acNewPLine.NumberOfVertices, new Point2d(acTmpPt.X, acTmpPt.Y), 0.0, 0.0, 0.0);
                               }
                               acNewPLine.Closed = true;
                           }
                           break;
                     }
                   }

                   DBObjectCollection acDboCol_2 = null;
                   try
                   {
                     acDboCol_2 = acNewPLine.GetSplitCurves(acPt3dCol_2);
                     foreach (Entity acEnt2 in acDboCol_2)
                     {
                           Polyline acNewPLine2 = acEnt2 as Polyline;
                           acNewPLine2.Closed = true;

                           MyCustomObject myCustomObj = new MyCustomObject();
                           myCustomObj.Vertices = new List<Point3d>();

                           for (int i = 0; i < acNewPLine2.NumberOfVertices; i++)
                           {
                               myCustomObj.Vertices.Add(acNewPLine2.GetPoint3dAt(i));
                           }
                           myCustomObjList.Add(myCustomObj);
                           acNewPLine2.Dispose();
                     }
                   }
                   catch (Autodesk.AutoCAD.Runtime.Exception ex)
                   {
                     if (ex.ErrorStatus == Autodesk.AutoCAD.Runtime.ErrorStatus.InvalidInput)
                     {
                           MyCustomObject myCustomObj = new MyCustomObject();
                           myCustomObj.Vertices = new List<Point3d>();

                           for (int i = 0; i < acNewPLine2.NumberOfVertices; i++)
                           {
                               myCustomObj.Vertices.Add(acNewPLine2.GetPoint3dAt(i));
                           }
                           myCustomObjList.Add(myCustomObj);

                     }
                     else
                     {
                           // Throw out other exceptions
                           throw ex;
                     }
                   }
                   finally
                   {
                     acNewPLine.Dispose();
                     if (acDboCol_2 != null)
                           acDboCol_2.Dispose();
                   }
               }
         }
         finally
         {
               if (acDboCol_1 != null)
                   acDboCol_1.Dispose();
         }

SEANT 发表于 2022-7-6 23:42:37

 
 
 
这是LIST命令显示的内容。我只是在处理基于第一个顶点和最后一个顶点总是不同的概念的情况下提出来的。今天晚些时候我将不得不看上面的代码片段。
命令:列表
选择对象:找到1个
选择对象:找到1个,共2个
选择对象:
LW多段线图层:“0”
空间:模型空间
手柄=173
关闭
恒定宽度0.0000
面积50.0000
周长30.0000
在点X=0.0000 Y=0.0000 Z=0.0000处
在点X=10.0000 Y=0.0000 Z=0.0000处
在点X=10.0000 Y=5.0000 Z=0.0000处
在点X=0.0000 Y=5.0000 Z=0.0000处
LW多段线图层:“0”
空间:模型空间
手柄=175
关闭
恒定宽度0.0000
面积50.0000
周长30.0000
在点X=15.0000 Y=0.0000 Z=0.0000处
在点X=25.0000 Y=0.0000 Z=0.0000处
在点X=25.0000 Y=5.0000 Z=0.0000处
在点X=15.0000 Y=5.0000 Z=0.0000处
在点X=15.0000 Y=0.0000 Z=0.0000处

SEANT 发表于 2022-7-6 23:45:12

啊,是的,我现在看到了。这看起来确实有点可疑。
在很大程度上,我对API的性能感到满意,但偶尔也会遇到这些异常情况。我将查看Geometry名称空间中的类似调用,看看它是否有相同的怪癖。

stmoong 发表于 2022-7-6 23:49:01

谢谢,我不知道如何使用Curve2d。在几何体命名空间中找到GetSplitCurves,因为它需要一个双精度值作为输入参数。
页: [1] 2
查看完整版本: 使用GetSplitCurves(点