随笔 - 167  文章 - 2  评论 - 38  阅读 - 37万

Unity 将List<Vector2>排序

 给List<Vector2>排序一般有两种场景,一种时给处在同一条直线上的点进行排序,另一种是给多边形的顶点进行排序。

1、给直线上的点排序

我这里实现的逻辑是,首先给定直线上的两个点start和end,List<Vector2>按start到end的方向,从小到大排序。

可以看下这个测试示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void Vector2SortByLineTest(Vector2 lineStart,Vector2 lineEnd)
{
    Vector2 dir = (lineEnd - lineStart).normalized;
    DrawArrow(dir * -5, dir * 5, Color.red, "line");
    List<Vector2> v2s = new List<Vector2>();
    for (int i = 0; i < 5; i++)
    {
        float x = Random.Range(-3f, 3f);
        float y = (dir.y / dir.x) * x + Random.Range(-1f, 1f);
        v2s.Add(new Vector2(x, y));
    }
     
    SortVector2.ByLine(lineStart,lineEnd,v2s);
 
    foreach (var item in v2s)
    {
        GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        obj.name = v2s.IndexOf(item).ToString();
        obj.transform.localScale *= 0.2f;
        obj.transform.position = item;
    }
    for (int i = 0; i < v2s.Count - 1; i++)
    {
        DrawArrow(v2s[i], v2s[i + 1], Color.green, i.ToString());
    }
}

 看下效果:

首先通过DrawArrow方法画出直线,如图中红色线段所示,箭头方向就是List<Vector2>排序的方向;

然后随机生成5个Vector2,通过SortVector2.ByLine方法将随机生成的点进行排序;

可以看到绿色箭头指向的小球,已经按红色箭头方向排好了序。

我实现的SortVector2.ByLine排序方法有个优点时,就是点不必完全在直线上,任意的点也能按这种方式排序。

2、给多边形的顶点排序

 实现逻辑是,以给定的点为中心,List<Vector2>围绕中心点以顺时针方向进行排序,只适用于凸多边形,对于凹多边形也会把它看成凸多边形进行排序。

看测试的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void Vector2SortByClockwiseTest(Vector2 origin)
{
    List<Vector2> v2s = new List<Vector2>();
    //随机生成一些Vector2
    for (int i = 0; i < 15; i++)
    {
        float r = 3;
        float x = Random.Range(-r, r);
        float y = (Random.Range(-r, r) > 0 ? 1 : -1) * Mathf.Sqrt(r * r - x * x) + Random.Range(-1.5f, 1.5f);
        v2s.Add(new Vector2(x + origin.x, y + origin.y));
    }
    //按顺时针排序
    SortVector2.ByClockwise(origin, v2s);
 
    GameObject o= GameObject.CreatePrimitive(PrimitiveType.Sphere);
    Material mat= new Material(Shader.Find("Unlit/Color"));
    mat.color = Color.red;
    o.GetComponent<MeshRenderer>().material = mat;
    o.transform.localScale *= 0.2f;
    o.transform.position = origin;
    foreach (var item in v2s)
    {
        GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        obj.name = v2s.IndexOf(item).ToString();
        obj.transform.localScale *= 0.2f;
        obj.transform.position = item;
    }
 
    for (int i = 0; i < v2s.Count - 1; i++)
    {
        DrawArrow(v2s[i], v2s[i + 1], Color.green, i.ToString());
    }
}

  效果:

 

 红色的点就是中心点,各个小球就是排序后的点,绿色箭头标出了排序后的方向即顺时针排序的;

如果需要逆时针排序,只需先按顺时针排序后,再调用List的Reverse方法,将List反转一下就行。

 

这里 获取完整的该工程的源码,包含:排序的方法,示例demo

 

posted on   Jason_c  阅读(435)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示