对于任意给定的离散点搜索其边界,主要通过判断边界类型然后指定相应的搜索方式。一般边界主要分为凸边界和既有凸边界又有凹边界两种类型。如下图所示:
对于不同类型的边界有不同的计算算法搜索点,在搜索边界时,现约定统一采用逆时针方向搜索。如现已经存在边界AC,需要搜索下一条边界AB,如下图所示:
添加一个按钮,设置其Name和Text属性都为“凸边界搜索”。由于在搜索到边界时需要添加新的对象,所以采用ArrayList类型,需要添加引用“using System.Collections;” 同时定义类Edge用于保存该边界的起点与终点,如下: public class Edge { public int Start;//边的起点 public int End;//边的终点 } 在全局变量中添加定义“private ArrayList arrayEdges = new ArrayList();”用于定义边界数组。 为“凸边界搜索”按钮的Click事件添加代码如下: private void 凸边界搜索_Click(object sender, EventArgs e) { arrayEdges.Clear(); Microsoft.VisualBasic.Interaction.AppActivate(AcadApp.Caption); AcadSelectionSet mySelectionSet; mySelectionSet = AcadDoc.SelectionSets.Add("NewSelectionSet001"); Int16[] FilterType = new Int16[1]; object[] FilterData = new object[1]; FilterType[0] = 0; FilterData[0] = "POINT"; mySelectionSet.SelectOnScreen(FilterType, FilterData); double[] arrPoints = new double[3 * mySelectionSet.Count]; int count = 0; foreach (AcadObject acadObj in mySelectionSet) { if (acadObj.ObjectName == "AcDbPoint") { count++; double[] PointCoord; PointCoord = (Double[])(((AcadPoint)acadObj).Coordinates); arrPoints[3 * count - 3] = PointCoord[0]; arrPoints[3 * count - 2] = PointCoord[1]; arrPoints[3 * count - 1] = PointCoord[2]; } } AcadDoc.SelectionSets.Item("NewSelectionSet001").Delete(); //获取点集外围边界 int i, StartIndex=0, AIndex, BIndex, pointCount = arrPoints.Length / 3; for (i = 1; i < pointCount; i++) //寻找X值最小的点号 { if (arrPoints[3 * i] < arrPoints[3 * StartIndex]) { StartIndex = i; } } Edge edge = new Edge(); edge.Start = StartIndex; BIndex = StartIndex - 1; AIndex = StartIndex; double[] vector1 = new double[2], vector2 = new double[2]; vector1[0] = 0; vector1[1] = 100; double vector1Length, vector2Length, angleTemp, angleMax, lengthMin, vectorDirect; angleMax = 0; while (BIndex != StartIndex) { vector1Length = Math.Sqrt(vector1[0] * vector1[0] + vector1[1] * vector1[1]); lengthMin = 300; for (i = 0; i < pointCount; i++)//找边界 { if (i != edge.Start) { vector2[0] = arrPoints[3 * i] - arrPoints[3 * AIndex]; vector2[1] = arrPoints[3 * i + 1] - arrPoints[3 * AIndex + 1]; vector2Length = Math.Sqrt(vector2[0] * vector2[0] + vector2[1] * vector2[1]); angleTemp = Math.Acos((vector1[0] * vector2[0] + vector1[1] * vector2[1]) / (vector1Length * vector2Length)); vectorDirect = vector1[0] * vector2[1] - vector1[1] * vector2[0]; if (angleTemp > angleMax && vectorDirect<0) { angleMax = angleTemp; edge.End = i; lengthMin = vector2Length; } else if (angleTemp == angleMax && vector2Length < lengthMin) { edge.End = i; lengthMin = vector2Length; } } } arrayEdges.Add(edge); BIndex = edge.End; edge = new Edge(); edge.Start = BIndex; vector1[0] = arrPoints[3 * AIndex] - arrPoints[3 * BIndex]; vector1[1] = arrPoints[3 * AIndex + 1] - arrPoints[3 * BIndex + 1]; angleMax = 0; AIndex = BIndex; } //绘制边界 double[] lineCoords = new double[3*(arrayEdges.Count+1)]; Edge[] edges = new Edge[arrayEdges.Count]; arrayEdges.CopyTo(edges); for(i=0;i<arrayEdges.Count;i++) { double[] p1=new double[3]; p1[0] = arrPoints[3 * edges[i].Start]; p1[1] = arrPoints[3 * edges[i].Start+1]; p1[2] = arrPoints[3 * edges[i].Start+2]; lineCoords[3 * i] = arrPoints[3 * edges[i].Start]; lineCoords[3 * i + 1] = arrPoints[3 * edges[i].Start + 1]; lineCoords[3 * i + 2] = arrPoints[3 * edges[i].Start + 2]; } lineCoords[3 * arrayEdges.Count - 3] = arrPoints[3 * edges[arrayEdges.Count - 1].Start]; lineCoords[3 * arrayEdges.Count - 2] = arrPoints[3 * edges[arrayEdges.Count - 1].Start + 1]; lineCoords[3 * arrayEdges.Count - 1] = arrPoints[3 * edges[arrayEdges.Count - 1].Start + 2]; lineCoords[3 * arrayEdges.Count] = arrPoints[3 * edges[arrayEdges.Count-1].End]; lineCoords[3 * arrayEdges.Count+1] = arrPoints[3 * edges[arrayEdges.Count-1].End + 1]; lineCoords[3 * arrayEdges.Count+2] = arrPoints[3 * edges[arrayEdges.Count - 1].End + 2]; AcadDoc.ModelSpace.Add3DPoly(lineCoords); } 运行程序,其结果如下图所示: