153 lines
3.3 KiB
C#
153 lines
3.3 KiB
C#
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<Line2>();
|
|
|
|
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 );
|
|
}
|
|
|
|
|
|
|
|
}
|
|
} |