inz-00/Assets/Scripts/GraphGenerator.cs
2019-07-27 22:40:42 +02:00

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();
}
}
}
}