Revit中实现GH Scan凸包算法

             
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;
        }

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值