using System.Collections.Generic;
using UnityEngine;
namespace ProceduralToolkit.Skeleton
{
///
/// A straight skeleton representation
///
public class StraightSkeleton
{
public List> polygons = new List>();
public StraightSkeleton()
{
}
public StraightSkeleton(Plan plan)
{
foreach (var currentVertex in plan)
{
var nextVertex = currentVertex.next;
var polygon = new List {currentVertex.position, nextVertex.position};
currentVertex.nextPolygonIndex = polygons.Count;
currentVertex.previousPolygonIndex = polygons.Count - 1;
polygons.Add(polygon);
}
}
public void AddVertex(Plan.Vertex vertex)
{
if (vertex.previousPolygonIndex == vertex.nextPolygonIndex)
{
AddVertex(vertex.previousPolygonIndex, vertex.position);
}
else
{
AddVertex(vertex.previousPolygonIndex, vertex.position);
AddVertex(vertex.nextPolygonIndex, vertex.position);
}
}
public void ValidatePolygons()
{
foreach (var polygon in polygons)
{
ValidatePolygon(polygon);
}
}
private void AddVertex(int polygonIndex, Vector2 vertex)
{
var polygon = polygons.GetLooped(polygonIndex);
if (polygon.Count > 2)
{
for (int i = 2; i < polygon.Count; i++)
{
if (polygon[i] == vertex)
{
return;
}
}
polygon.Add(vertex);
}
else
{
polygon.Add(vertex);
}
}
private void ValidatePolygon(List polygon)
{
Vector2 controurDirection = polygon[1] - polygon[0];
int count = 0;
bool swapped;
do
{
swapped = false;
if (count > polygon.Count)
{
Debug.LogError("Too many iterations");
break;
}
for (int i = 3; i < polygon.Count; i++)
{
Vector2 current = polygon[i];
Vector2 previous = polygon[i - 1];
Vector2 edgeDirection = current - previous;
float dot = Vector2.Dot(controurDirection, edgeDirection);
if (dot < -Geometry.Epsilon)
{
// Contradirected
}
else if (dot > Geometry.Epsilon)
{
// Codirected
polygon[i] = previous;
polygon[i - 1] = current;
swapped = true;
}
else
{
// Perpendicular
Vector2 next = polygon.GetLooped(i + 1);
Vector2 previousPrevious = polygon[i - 2];
if (Intersect.SegmentSegment(current, next, previous, previousPrevious))
{
polygon[i] = previous;
polygon[i - 1] = current;
swapped = true;
}
}
}
count++;
} while (swapped);
}
}
}