+
+static void closest_point_elipse( v2f p, v2f e, v2f o )
+{
+ v2f pabs, ei, e2, ve, t;
+
+ v2_abs( p, pabs );
+ v2_div( (v2f){ 1.0f, 1.0f }, e, ei );
+ v2_mul( e, e, e2 );
+ v2_mul( ei, (v2f){ e2[0]-e2[1], e2[1]-e2[0] }, ve );
+
+ v2_fill( t, 0.70710678118654752f );
+
+ for( int i=0; i<3; i++ )
+ {
+ v2f v, u, ud, w;
+
+ v2_mul( ve, t, v ); /* ve*t*t*t */
+ v2_mul( v, t, v );
+ v2_mul( v, t, v );
+
+ v2_sub( pabs, v, u );
+ v2_normalize( u );
+
+ v2_mul( t, e, ud );
+ v2_sub( ud, v, ud );
+
+ v2_muls( u, v2_length( ud ), u );
+
+ v2_add( v, u, w );
+ v2_mul( w, ei, w );
+
+ v2_maxv( (v2f){0.0f,0.0f}, w, t );
+ v2_normalize( t );
+ }
+
+ v2_mul( t, e, o );
+ v2_copysign( o, p );
+}
+