using Godot; namespace Rokojori { public class SVGArc { public static Vector2 GetPointOnCenterArc( Vector2 r, float theta, float delta ) { return new Vector2( r.X * Mathf.Cos( theta ) * Mathf.Cos( delta ) - r.Y * Mathf.Sin( theta ) * Mathf.Sin( delta ), r.X * Mathf.Sin( theta ) * Mathf.Cos( delta ) + r.Y * Mathf.Cos( theta ) * Mathf.Sin( delta ) ); } public static void EndpointToCenterArc( Vector2 start, Vector2 end, Vector2 radius, float xAngle, bool flagA, bool flagS, out Vector2 centerPosition, out Vector2 centerRadius, out Vector2 centerAngles ) { var rX = Mathf.Abs( radius.X ); var rY = Mathf.Abs( radius.Y ); var dx2 = ( start.X - end.X ) / 2f; var dy2 = ( start.Y - end.Y ) / 2f; var x1p = Mathf.Cos( xAngle ) * dx2 + Mathf.Sin( xAngle ) * dy2; var y1p = -Mathf.Sin( xAngle ) * dx2 + Mathf.Cos( xAngle ) * dy2; var rxs = rX * rX; var rys = rY * rY; var x1ps = x1p * x1p; var y1ps = y1p * y1p; var cr = x1ps / rxs + y1ps / rys; if ( cr > 1 ) { var s = Mathf.Sqrt( cr ); rX = s * rX; rY = s * rY; rxs = rX * rX; rys = rY * rY; } var dq = ( rxs * y1ps + rys * x1ps ); var pq = ( rxs * rys - dq ) / dq; var q = Mathf.Sqrt( Mathf.Max( 0, pq ) ); if ( flagA == flagS ) { q = -q; } var cxp = q * rX * y1p / rY; var cyp = - q * rY * x1p / rX; var cx = Mathf.Cos( xAngle ) * cxp - Mathf.Sin( xAngle ) * cyp + ( start.X + end.X ) / 2; var cy = Mathf.Sin( xAngle ) * cxp + Mathf.Cos( xAngle ) * cyp + ( start.Y + end.Y ) / 2; var theta = Angle( 1f, 0f, ( x1p-cxp ) / rX, ( y1p - cyp ) / rY ); var delta = Angle( ( x1p - cxp ) / rX, ( y1p - cyp ) / rY, ( -x1p - cxp ) / rX, ( -y1p-cyp ) / rY ); delta = delta % Mathf.Pi * 2; if ( ! flagS ) { delta -= 2 * Mathf.Pi; } centerRadius = new Vector2( rX, rY ); centerPosition = new Vector2(cx, cy ); centerAngles = new Vector2( theta, delta ); } static float Angle( float ux, float uy, float vx, float vy ) { var u = new Vector2( ux, uy ); var v = new Vector2( vx, vy ); var dot = Math2D.Dot( u, v ); var len = u.Length( ) * v.Length( ); var ang = Mathf.Acos( Mathf.Clamp( dot / len,-1,1 ) ); if ( ( u.X * v.Y - u.Y * v.X ) < 0 ) { ang = -ang; } return ang; } } }