using System.Collections; using System.Collections.Generic; using Godot; namespace Rokojori { public class Convex2Group { public List items; public Box2 boundingBox; public static Convex2Group From( List 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 points; public List normals; public List 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 PathToConvexList( Path2 path ) { var convexPolys = Geometry2D.DecomposePolygonInConvex( path.points.ToArray() ); var list = new List(); 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( points ), isClockwise ); } public static Convex2 FromConvexHull( List points, bool isClockwise = true ) { var cnv = new Convex2(); cnv.points = points; cnv.normals = new List(); cnv.directions = new List(); 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; } } }