仅提供中文版本
ConvertHullAlgorithm (凸包算法)
引用
《计算几何》-导言:凸包的例子
前言
- 算法的基本逻辑与理念来自于《计算几何》这本书,后面其他几章的演示也都会在Revit中实现调试,希望能够每个算法都找一个合适的实现方向在Revit中实现
- 所有的代码都是c#编写并在Revit中调试,因为部分接口与判定使用了Revit API,如果想单纯运行算法可以修改部分API到常用库
算法逻辑
算法比较简单,主要是获取一个点集合的外围边界,通过对点与向量相比较从而获取边界区域。

- 算法将所有点集按照点的X值从小到大排序,排序完成后连接最左侧的点与最右侧的点可以看到会将整个子集分割为两个子集:上子集,下子集

- 如果找到边界则代表边界点将会包围所有的点,故边界点两两连接后将会是最大的向量,保证向量右侧没有其他的点,视为边界点

- 通过上面的步骤,可以创建一个遍历,获得最外侧向量并逐步向最大值位置推进,从而描绘出边界区域

在完成上子集遍历后(及点推进到了X值最大点),将顺时针继续遍历子集,此时需要将整个数组的集合按照从大到小转置,并将参照的向量Dir修改为(TheRight - TheLeft)

最左侧断点与最右侧断点相互成为起点,终点后,即可完成所有的边界遍历。
代码
- 创建一个判定,两个向量的方向性,最开始以两个起始点的向量为比较向量,首先遍历上子集,则需要判定目标向量是否在次向量的上方或是左侧.
在判定位置使用了向量叉乘,并判断向量的Z值,原理是:通过计算法向量根据左手法则可以判定向量的旋转方向,从而判定两个向量的位置关系

1 | /// <summary> |
- 创建遍历的函数,此处放上书中的伪代码与c#代码解释。
1 | 算法 CONVEXHULL(P) |
- 定义起始点
TheLeft,终止点TheLast和点集集合vertices - 集合与
TheLeft的向量并与fakeDir = TheLast - TheLeft判定是否在右侧,如果点在向量右侧,则将点Point的数据迭代,替换掉fakeDir,并进入下一次循环,查找是否在fakeDir的右侧 - 循环结束后将最右侧点添加到集合中,从而查找出所有的边界点
1 | private List<XYZ> GetHullVertices(bool isUp = true) |
运行结果


Author: Broccoli
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles

2023-05-09
Creating Parts in Revit Secondary Development

2022-09-04
Revit二次开发 创建空心模型并与指定构件剪切

2023-05-16
Breaking an Arc into Multiple Segments

2023-06-16
Revit API Ray Method Returns Two Values for Same Element Analysis

2023-05-22
Revit二次开发 Grid无法获取reference的报错

2024-11-20
Implementing Multi-Category Tags in Revit