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

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