190 lines
5.8 KiB
C#
190 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Assets.Generators;
|
|
using Assets.Voronoi;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using Random = System.Random;
|
|
|
|
namespace Assets
|
|
{
|
|
[Serializable]
|
|
public class GraphGeneratorDebug
|
|
{
|
|
public bool enabled = true;
|
|
public bool displayPoints = true;
|
|
public bool displayBeachLine = true;
|
|
public bool displayParabolas = false;
|
|
public bool displayVertices = true;
|
|
public bool displayNeighbours = false;
|
|
public bool displayLabels= false;
|
|
}
|
|
|
|
[RequireComponent(typeof(MeshRenderer), typeof(MeshFilter)), ExecuteInEditMode]
|
|
public class GraphGenerator : MonoBehaviour
|
|
{
|
|
MeshFilter _filter;
|
|
private PoissonDiskSampler _sampler;
|
|
IList<Vector3> _points = new List<Vector3>();
|
|
|
|
public VoronoiGenerator generator;
|
|
public int seed = Environment.TickCount;
|
|
public Vector2 size = new Vector2();
|
|
public GraphGeneratorDebug debug;
|
|
[Range(2.0f, 64.0f)]
|
|
public float radius = 8;
|
|
|
|
private double _directrix = 0.0f;
|
|
|
|
private Random _random;
|
|
private Dictionary<Vector3, Color> _colors;
|
|
|
|
void Start()
|
|
{
|
|
_filter = GetComponent<MeshFilter>();
|
|
|
|
Reset();
|
|
}
|
|
|
|
public Vector3 RandomPoint()
|
|
{
|
|
return _points[_random.Next(_points.Count)];
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
_colors = new Dictionary<Vector3, Color>();
|
|
_random = new System.Random(seed);
|
|
|
|
_sampler = new PoissonDiskSampler(radius);
|
|
_sampler.Generator = _random;
|
|
|
|
_points = new List<Vector3>(_sampler.Generate(size.x, size.y));
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
_colors[RandomPoint()] = Color.yellow;
|
|
}
|
|
|
|
// points = new List<Vector3>()
|
|
// {
|
|
// new Vector3(15.7f, 5.9f),
|
|
// new Vector3(37.9f, 10.3f),
|
|
// new Vector3(24.6f, 18.1f),
|
|
// new Vector3(53.5f, 8.0f),
|
|
// };
|
|
|
|
generator = new VoronoiGenerator(_points.Select(x => new Point(x.x, x.y)).ToList());
|
|
}
|
|
|
|
public void Generate()
|
|
{
|
|
generator.Generate();
|
|
}
|
|
|
|
public void Step()
|
|
{
|
|
generator.Step();
|
|
_directrix = generator.Line.Directrix;
|
|
}
|
|
|
|
void OnDrawGizmos()
|
|
{
|
|
|
|
if (!debug.enabled) return;
|
|
|
|
if (debug.displayPoints)
|
|
{
|
|
|
|
foreach (var point in _points)
|
|
{
|
|
Gizmos.color = _colors.ContainsKey(point) ? _colors[point] : Color.white;
|
|
Gizmos.DrawSphere(point, 1);
|
|
|
|
if (debug.displayLabels) Handles.Label(point, $"({point.x:F1}, {point.y:F1})");
|
|
}
|
|
}
|
|
|
|
if (generator is null) return;
|
|
|
|
if (debug.displayNeighbours)
|
|
{
|
|
Gizmos.color = Color.yellow;
|
|
|
|
foreach (var site in generator.Sites)
|
|
{
|
|
var vecStart = new Vector3((float)site.Point.x, (float)site.Point.y);
|
|
foreach (var neighbour in site.Neighbours)
|
|
{
|
|
var vecEnd = new Vector3((float)neighbour.Point.x, (float)neighbour.Point.y);
|
|
Gizmos.DrawLine(vecStart, vecEnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Gizmos.color = Color.green;
|
|
foreach (var edge in generator.Edges)
|
|
{
|
|
var vecStart = new Vector3((float)edge.start.x, (float)edge.start.y);
|
|
var vecEnd = new Vector3((float)edge.end.x, (float)edge.end.y);
|
|
|
|
Gizmos.DrawLine(vecStart, vecEnd);
|
|
}
|
|
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawLine(new Vector3(0, (float)generator.Line.Directrix), new Vector3(size.x, (float)generator.Line.Directrix));
|
|
Gizmos.color = Color.blue;
|
|
|
|
Vector3 start;
|
|
|
|
if (debug.displayParabolas)
|
|
{
|
|
foreach (var parabola in generator.Line.Parabolas)
|
|
{
|
|
start = new Vector3(-size.x, (float)generator.Line.EvalParabola(parabola.Site.Point, -size.x));
|
|
for (var x = -size.x + 0.1f; x < size.x * 2; x += 0.1f)
|
|
{
|
|
var point = new Vector3(x, (float)generator.Line.EvalParabola(parabola.Site.Point, x));
|
|
Gizmos.DrawLine(start, point);
|
|
|
|
start = point;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (debug.displayVertices)
|
|
{
|
|
foreach (var vertex in generator.Vertices)
|
|
{
|
|
var point = new Vector3((float)vertex.x, (float)vertex.y);
|
|
|
|
Gizmos.DrawSphere(point, 1);
|
|
if (debug.displayLabels) Handles.Label(point, $"({point.x:F1}, {point.y:F1})");
|
|
}
|
|
}
|
|
|
|
if (debug.displayBeachLine)
|
|
{
|
|
Gizmos.color = Color.white;
|
|
start = new Vector3(-size.x, (float)generator.Line.Eval(-size.x));
|
|
for (var x = -size.x + 0.1f; x < size.x * 2; x += 0.1f)
|
|
{
|
|
var point = new Vector3(x, (float)generator.Line.Eval(x));
|
|
Gizmos.DrawLine(start, point);
|
|
|
|
start = point;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Rewind(float y)
|
|
{
|
|
while (generator.Line.Directrix < y && !generator.Done)
|
|
{
|
|
generator.Step();
|
|
}
|
|
}
|
|
}
|
|
} |