Unity 凸包算法在UI上任意点找到外围点集合

项目需求:在UI上任意点击几个点,点击完成后,找到最外围的点。

20240521_143301

代码示例:将点传入方法中即可

 // 计算凸包的Graham扫描算法
 public static List<Vector2> CalculateConvexHull(List<Vector2> points)
 {
   
     if (points.Count < 3)
     {
         Debug.LogError("点的数量少于3个,无法计算凸包");
         return new List<Vector2>();
     }

     // 复制点列表
     List<Vector2> sortedPoints = new List<Vector2>(points);
     // 按y坐标排序,如果y坐标相等按x坐标排序
     sortedPoints.Sort((a, b) =>
     {
         if (a.y != b.y)
             return a.y.CompareTo(b.y);
         return a.x.CompareTo(b.x);
     });

     // 起点为排序后第一个点
     Vector2 startPoint = sortedPoints[0];
     sortedPoints.RemoveAt(0);

     // 按极角排序
     sortedPoints.Sort((a, b) =>
     {
         float angleA = Mathf.Atan2(a.y - startPoint.y, a.x - startPoint.x);
         float angleB = Mathf.Atan2(b.y - startPoint.y, b.x - startPoint.x);
         return angleA.CompareTo(angleB);
     });

     // 创建栈用于存储凸包点
     Stack<Vector2> hull = new Stack<Vector2>();
     hull.Push(startPoint);
     hull.Push(sortedPoints[0]);

     for (int i = 1; i < sortedPoints.Count; i++)
     {
         Vector2 top = hull.Pop();

         // 检查方向(逆时针)
         while (hull.Count >= 1 && CrossProduct(hull.Peek(), top, sortedPoints[i]) <= 0)
         {
             top = hull.Pop();
         }

         hull.Push(top);
         hull.Push(sortedPoints[i]);
     }

     // 转换栈为列表
     List<Vector2> convexHull = new List<Vector2>(hull);

     List<Vector3> returnV3=new List<Vector3>();

     foreach (Vector2 v2 in convexHull)
     {
         // 获取点的屏幕坐标
         Vector2 screenPoint = UI.Camera.ScreenToWorldPoint(v2);
         returnV3.Add(screenPoint);
     }

     return returnV3;
 }

 // 计算叉积
 static float CrossProduct(Vector2 a, Vector2 b, Vector2 c)
 {
     return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
 }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值