146 lines
3.2 KiB
C#
146 lines
3.2 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Godot;
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class Convex2Group
|
|
{
|
|
public List<Convex2> items;
|
|
public Box2 boundingBox;
|
|
|
|
public static Convex2Group From( List<Convex2> items )
|
|
{
|
|
var group = new Convex2Group();
|
|
|
|
group.items = items;
|
|
|
|
group.boundingBox = items[ 0 ].boundingBox.Clone();
|
|
|
|
items.ForEach( it => group.boundingBox.UnionWith( it.boundingBox ) );
|
|
|
|
// RJLog.Log( group.boundingBox );
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
public static Convex2Group FromPath( Path2 path )
|
|
{
|
|
return From( Convex2.PathToConvexList( path ) );
|
|
}
|
|
|
|
public bool ContainsPoint( Vector2 point )
|
|
{
|
|
if ( ! boundingBox.ContainsPoint( point ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for ( int i = 0; i < items.Count; i++ )
|
|
{
|
|
if ( items[ i ].ContainsPoint( point ) )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
}
|
|
|
|
public class Convex2
|
|
{
|
|
public List<Vector2> points;
|
|
public List<Vector2> normals;
|
|
public List<Vector2> directions;
|
|
|
|
public Box2 boundingBox;
|
|
public bool clockwise;
|
|
|
|
public bool ContainsPoint( Vector2 point, bool checkBounds = true )
|
|
{
|
|
if ( checkBounds && ! boundingBox.ContainsPoint( point ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var positive = 0;
|
|
var negative = 0;
|
|
|
|
for ( int i = 0; i < points.Count; i++ )
|
|
{
|
|
var p = points[ i ];
|
|
var d = directions[ i ].Cross( point - p );
|
|
|
|
if ( d > 0 )
|
|
{
|
|
positive++;
|
|
}
|
|
|
|
if ( d < 0 )
|
|
{
|
|
negative++;
|
|
}
|
|
|
|
if ( positive > 0 && negative > 0 )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
public static List<Convex2> PathToConvexList( Path2 path )
|
|
{
|
|
var convexPolys = Geometry2D.DecomposePolygonInConvex( path.points.ToArray() );
|
|
|
|
var list = new List<Convex2>();
|
|
|
|
for ( int i = 0; i < convexPolys.Count; i++ )
|
|
{
|
|
var clockwise = Geometry2D.IsPolygonClockwise( convexPolys[ i ] );
|
|
var cnv = FromConvexHull( convexPolys[ i ], clockwise );
|
|
|
|
list.Add( cnv );
|
|
}
|
|
|
|
// RJLog.Log( "PathToConvexList:", list.Count );
|
|
return list;
|
|
}
|
|
|
|
public static Convex2 FromConvexHull( Vector2[] points, bool isClockwise = true )
|
|
{
|
|
return FromConvexHull( new List<Vector2>( points ), isClockwise );
|
|
}
|
|
|
|
public static Convex2 FromConvexHull( List<Vector2> points, bool isClockwise = true )
|
|
{
|
|
var cnv = new Convex2();
|
|
cnv.points = points;
|
|
cnv.normals = new List<Vector2>();
|
|
cnv.directions = new List<Vector2>();
|
|
cnv.clockwise = isClockwise;
|
|
|
|
cnv.boundingBox = new Box2( points[ 0 ], points[ 0 ] );
|
|
|
|
for ( int i = 0; i < points.Count; i++ )
|
|
{
|
|
var next = ( i + 1 ) % points.Count;
|
|
|
|
cnv.boundingBox.GrowByPoint( points[ i ] );
|
|
|
|
var direction = points[ next ] - points[ i ];
|
|
var normal = Math2D.Rotate90Degrees( direction.Normalized(), ! isClockwise );
|
|
|
|
cnv.normals.Add( normal );
|
|
cnv.directions.Add( direction );
|
|
}
|
|
|
|
return cnv;
|
|
}
|
|
}
|
|
} |