Revit中实现GH Scan凸包算法

该博客详细介绍了计算几何中求解二维平面上点集的凸包问题的算法,提供了一个C#实现的ConvexHull函数。首先检查点的数量,如果少于3个直接返回。接着找到最低点并按角度排序,使用单调链方法构建凸包。此外,还定义了辅助函数用于判断三点是否构成左转。整个过程高效地构建了凸包并返回结果。
摘要由CSDN通过智能技术生成
             
public static IEnumerable<XYZ> ConvexHull(IEnumerable<XYZ> points)
        {
            if (points.Count() < 3)
            {
                return points;
            }
            var inputPoints = new List<XYZ>(points);
            var llt = FindLowestThenLeftPoint(inputPoints);
            var res = new List<XYZ>();

            inputPoints = inputPoints.OrderBy(x => (x - llt).Normalize().AngleTo(XYZ.BasisX)).ToList();

            var stack = inputPoints.ToArray();

            var lowPtr = 1;
            var upPtr = 2;

            while (upPtr != stack.Length)
            {
                var p1 = stack[lowPtr];
                var p2 = stack[lowPtr - 1];

                var candidate = stack[upPtr];

                var left = ToLeft(p2, p1, candidate);
                if (left > 0)
                {
                    stack[++lowPtr] = stack[upPtr++];
                }
                else
                {
                    lowPtr--;
                }
            }
            return stack.ToList().Take(lowPtr + 1);
        }

      
private static XYZ FindLowestThenLeftPoint(IEnumerable<XYZ> points)
        {
            var res = points.FirstOrDefault();

            var enumerator = points.GetEnumerator();
            while (enumerator.MoveNext())
            {
                var temp = enumerator.Current as XYZ;
                if (temp.Y < res.Y)
                {
                    res = temp;
                }
                else if (temp.Y == res.Y)
                {
                    res = temp.X < res.X ? temp : res;
                }
            }
            return res;
        }



public static int ToLeft(XYZ p1, XYZ p2, XYZ p3, double eps = 1e-4)
        {
            var area = p1.X * p2.Y - p1.Y * p2.X
                    + p2.X * p3.Y - p2.Y * p3.X
                    + p3.X * p1.Y - p3.Y * p1.X;
            if (Math.Abs(area) < eps)
            {
                return 0;
            }

            return area > 0 ? 1 : -1;
        }

效果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值