Unity 将List<Vector2>排序

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

1、给直线上的点排序

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

可以看下这个测试示例:

    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>围绕中心点以顺时针方向进行排序,只适用于凸多边形,对于凹多边形也会把它看成凸多边形进行排序。

看测试的示例:

    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 2022-02-22 20:12  Jason_c  阅读(405)  评论(0编辑  收藏  举报