凸边界搜索

对于任意给定的离散点搜索其边界,主要通过判断边界类型然后指定相应的搜索方式。一般边界主要分为凸边界和既有凸边界又有凹边界两种类型。如下图所示:

对于不同类型的边界有不同的计算算法搜索点,在搜索边界时,现约定统一采用逆时针方向搜索。如现已经存在边界AC,需要搜索下一条边界AB,如下图所示:

添加一个按钮,设置其NameText属性都为“凸边界搜索”。由于在搜索到边界时需要添加新的对象,所以采用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);

}

运行程序,其结果如下图所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值