보로노이 다이어그램 (Voronoi diagram)
보로노이 다이어그램은 주어진 평면 위의 점 집합에서,
각 점에 대해 해당 점과 가장 가까운 영역을 나누는 공간 분할 방법으로 여러가지 과학적 및 공학적 분야에서 자주 사용된다. 특정 전체를 기준으로 분할되기 때문에 어느정도의 일정구역을 차지하게 된다.
반응형
< Voronoi Diagram >
Map Size 에서 Point Count 만큼 영역을 생성하는 로직이다.
< Voronoi Diagram >
using System.Collections.Generic;
using UnityEngine;
public class VoronoiDiagram : MonoBehaviour
{
public int pointCount = 10;
public Vector2 mapSize = new Vector2(10, 10);
private List<Vector2> points;
private Texture2D voronoiTexture;
void Start()
{
// 카메라 설정
Camera.main.transform.position = new Vector3(mapSize.x / 2, mapSize.y / 2, -10);
Camera.main.orthographic = true;
Camera.main.orthographicSize = mapSize.y / 2;
// 랜덤 점들 생성
points = GenerateRandomPoints(pointCount);
// Voronoi 다이어그램을 위한 텍스처 생성
voronoiTexture = new Texture2D((int)mapSize.x * 100, (int)mapSize.y * 100);
// 다이어그램 생성
GenerateVoronoiDiagram();
// 텍스처를 적용할 Quad 생성
GameObject quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
quad.transform.SetParent(transform);
// Quad의 위치를 가운데로 설정 (Gizmos와 맞춤)
quad.transform.position = new Vector3(mapSize.x / 2, mapSize.y / 2, 0) + transform.position;
quad.transform.localScale = new Vector3(mapSize.x, mapSize.y, 1);
quad.GetComponent<Renderer>().material.mainTexture = voronoiTexture;
}
List<Vector2> GenerateRandomPoints(int count)
{
List<Vector2> result = new List<Vector2>();
for (int i = 0; i < count; i++)
{
result.Add(new Vector2(Random.Range(0, mapSize.x), Random.Range(0, mapSize.y)));
}
return result;
}
void GenerateVoronoiDiagram()
{
for (int y = 0; y < voronoiTexture.height; y++)
{
for (int x = 0; x < voronoiTexture.width; x++)
{
// 픽셀 좌표를 월드 좌표로 변환 (Gizmos와 일치)
Vector2 pixelPosition = new Vector2(
(float)x / voronoiTexture.width * mapSize.x,
(float)y / voronoiTexture.height * mapSize.y
) + (Vector2)transform.position; // Transform 적용
int closestPointIndex = GetClosestPoint(pixelPosition);
voronoiTexture.SetPixel(x, y, GetColorForPoint(closestPointIndex));
}
}
voronoiTexture.Apply();
}
int GetClosestPoint(Vector2 position)
{
int closestIndex = 0;
float closestDistance = Vector2.Distance(position, points[0] + (Vector2)transform.position); // Transform 적용
for (int i = 1; i < points.Count; i++)
{
float distance = Vector2.Distance(position, points[i] + (Vector2)transform.position); // Transform 적용
if (distance < closestDistance)
{
closestDistance = distance;
closestIndex = i;
}
}
return closestIndex;
}
Color GetColorForPoint(int pointIndex)
{
int hash = pointIndex.GetHashCode();
Random.InitState(hash);
return new Color(Random.value, Random.value, Random.value);
}
void OnDrawGizmos()
{
if (points == null)
return;
Gizmos.color = Color.red;
foreach (var point in points)
{
// Transform 좌표를 반영하여 Gizmos에서 점을 그리기
Gizmos.DrawSphere(new Vector3(point.x, point.y, 0) + transform.position, 0.1f);
}
}
}
★★★☆☆
반응형
'개발 > Unity' 카테고리의 다른 글
Unity) 오프스크린 인디케이터(off-screen indicator) (0) | 2024.10.24 |
---|---|
Unity) Project Settings의 특정 메뉴 선택하기 (0) | 2024.10.22 |
Unity) 재화 획득 연출(흩뿌리고 타겟 이동 연출) (0) | 2024.10.18 |
Unity) Debug -Json Pretty Print 적용하기 (0) | 2024.10.10 |
Unity)격투 게임 HP 구현하기 (Recoverable HP :회복 가능 HP) (0) | 2024.10.08 |
댓글