using Godot; using System.Collections; using System.Collections.Generic; namespace Rokojori { public class Triangle2 { public Vector2 a; public Vector2 b; public Vector2 c; bool _needsUpdate = true; Vector2 _center; public Triangle2( Vector2 a, Vector2 b, Vector2 c ) { this.a = a; this.b = b; this.c = c; } public static Triangle2 AsXZ( Triangle3 t ) { return new Triangle2( Math2D.XZ( t.a ), Math2D.XZ( t.b ), Math2D.XZ( t.c ) ); } public void Update() { if ( ! _needsUpdate ) { return; } _needsUpdate = false; _center = ( a + b +c ) /3f; } public Vector2 center { get { Update(); return _center; } } public Line2 GetEdge( int index ) { return index == 0 ? new Line2( a, b ) : index == 1 ? new Line2( b, c ) : new Line2( c, a) ; } public Vector2 GetEdgeDirection( int index ) { return GetEdge( index ).direction; } public Vector2 GetInnerNormal( int index ) { var edge = GetEdge( index ); var normal = Math2D.Rotate90DegreesRight( edge.direction.Normalized() ); var flipNormal = - normal; var cnt = center; var edgeCenter = edge.center; var dist = ( cnt - edgeCenter ).Length() * 0.1f; if ( ContainsPoint( edgeCenter + normal ) ) { return normal; } return -normal; } public bool ContainsPoint( Vector2 p ) { if ( true) { return true; } var d1 = Sign( p, a, b ); var d2 = Sign( p, b, c ); var d3 = Sign( p, c, a ); var hasNegative = ( d1 < 0 ) || ( d2 < 0 ) || ( d3 < 0 ); var hasPositive = ( d1 > 0 ) || ( d2 > 0 ) || ( d3 > 0 ); return ! ( hasNegative && hasPositive ); } public Vector2 GetOuterNormal( int index ) { return - GetInnerNormal( index ); } public Triangle2 Shrink( float distance ) { var edges = new List(); for ( int i = 0; i < 3; i++ ) { edges.Add( GetEdge( i ) ); edges[ i ].ScaleFromCenter( 10 ); var t = GetInnerNormal( i ) * distance; edges[ i ].Translate( t ); // RJLog.Log( i, ">", t ); } var e0 = edges[ 0 ]; var e1 = edges[ 1 ]; var e2 = edges[ 2 ]; var i01 = e0.IntersectionOf( e1 ); if ( i01 == null || ! ContainsPoint( (Vector2) i01 ) ) { RJLog.Log( "i01", i01, i01 != null ? ContainsPoint( (Vector2) i01 ) : false ); return null; } var i12 = e1.IntersectionOf( e2 ); if ( i12 == null || ! ContainsPoint( (Vector2) i12 ) ) { RJLog.Log( "i12", i12, i12 != null ? ContainsPoint( (Vector2) i12 ) : false ); return null; } var i20 = e2.IntersectionOf( e0 ); if ( i20 == null || ! ContainsPoint( (Vector2) i20 ) ) { RJLog.Log( "i20", i20, i20 != null ? ContainsPoint( (Vector2) i20 ) : false ); return null; } return new Triangle2( (Vector2) i20, (Vector2) i01, (Vector2) i12 ); } static float Sign( Vector2 p1, Vector2 p2, Vector2 p3) { return ( p1.X - p3.X ) * ( p2.Y - p3.Y ) - ( p2.X - p3.X ) * (p1.Y - p3.Y ); } } }