Unity实现Voronoi图(性能友好,分布较为均匀

 

这是一种性能友好的并且生成较为均匀的Voronoi图的实现方式

 

 在一张网格中生成随机点,然后在取每个点周围点就不需要去做全局遍历,在自己周围的格子遍历即可

using UnityEngine;
using UnityEngine.UI;

public class VoronoiDiagram : MonoBehaviour
{
    public int gridSize = 10;
    private int imgSize;
    private RawImage image;
    private int pixelsPerCell;
    private Vector2Int[,] pointsPositions;
    private Color[,] colors;

    void Start()
    {
        image = GetComponent<RawImage>();
        imgSize = Mathf.RoundToInt(image.GetComponent<RectTransform>().sizeDelta.x);
        GnerateDiagram();
    }

    void GnerateDiagram()
    {
        Texture2D texture = new Texture2D(imgSize, imgSize);
        texture.filterMode = FilterMode.Point;
        pixelsPerCell = imgSize / gridSize;
        GeneratePoints();

        for (int i = 0; i < imgSize; i++)
        {
            for (int j = 0; j < imgSize; j++)
            {
                int gridX = i / pixelsPerCell;
                int gridY = j / pixelsPerCell;

                float nearestDistance = Mathf.Infinity;
                Vector2Int nearestPoint = new Vector2Int();

                // 取九宫格周围的点
                for (int a = -1; a < 2; a++)
                {
                    for (int b = -1; b < 2; b++)
                    {
                        int X = gridX + a;
                        int Y = gridY + b;
                        if (X < 0 || Y < 0 || X >= gridSize || Y >= gridSize)
                        {
                            continue;
                        }

                        float distance = Vector2Int.Distance(new Vector2Int(i, j), pointsPositions[X, Y]);
                        if (distance < nearestDistance)
                        {
                            nearestDistance = distance;
                            nearestPoint = new Vector2Int(X, Y);
                        }
                    }
                }

                texture.SetPixel(i, j, colors[nearestPoint.x, nearestPoint.y]);
            }
        }

        texture.Apply();
        image.texture = texture;
    }

    private void GeneratePoints()
    {
        pointsPositions = new Vector2Int[gridSize, gridSize];
        colors = new Color[gridSize, gridSize];
        for (int i = 0; i < gridSize; i++)
        {
            for (int j = 0; j < gridSize; j++)
            {
                pointsPositions[i, j] = new Vector2Int(i * pixelsPerCell + Random.Range(0, pixelsPerCell),
                    j * pixelsPerCell + Random.Range(0, pixelsPerCell));

                float r = Random.Range(0, 1f);
                float g = Random.Range(0, 1f);
                float b = Random.Range(0, 1f);
                Color c = new Color(r, g, b, 1);
                colors[i, j] = c;
            }
        }
    }
}

 

关键字:泰森多边形;沃洛诺伊图

口述:

分散的每个点分别代表一种颜色点

遍历图片的每个像素点,每个像素点查找与自己最近的是哪个颜色点就把当前像素点染成这个颜色

为了性能考虑我们划分了格子,所有只用查找自己周围的九宫格的点判断距离就行,不用和每个颜色点做距离比较

简单理解:假设一个格子里面有2个颜色点,遍历这个格子的每个像素,像素距离哪个颜色点近就染成什么颜色,最终会得到以2个颜色点的一个垂直平分线的颜色划分的2块颜色区域

posted @ 2023-11-18 17:33  三页菌  阅读(49)  评论(0编辑  收藏  举报