rj-action-library/Runtime/Math/Geometry/Convex2.cs

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