public float GetClosestPointOnEdge(Vector2 point, int edgeNum, out Vector2 hitPt, out Vector2 normal, out float edgeD)
{
hitPt = new Vector2();
hitPt.X = 0f;
hitPt.Y = 0f;
normal = new Vector2();
normal.X = 0f;
normal.Y = 0f;
edgeD = 0f;
float dist = 0f;
Vector2 ptA = pointmass_list[edgeNum].position;
Vector2 ptB = new Vector2();
if (edgeNum < (count - 1))
ptB = pointmass_list[edgeNum + 1].position;
else
ptB = pointmass_list[0].position;
Vector2 toP = new Vector2();
toP.X = point.X - ptA.X;
toP.Y = point.Y - ptA.Y;
Vector2 E = new Vector2();
E.X = ptB.X - ptA.X;
E.Y = ptB.Y - ptA.Y;
// get the length of the edge, and use that to normalize the vector.
float edgeLength = (float)Math.Sqrt((E.X * E.X) + (E.Y * E.Y));
if (edgeLength > 0.00001f)
{
E.X /= edgeLength;
E.Y /= edgeLength;
}
// normal
Vector2 n = new Vector2();
VectorHelper.Perpendicular(ref E, ref n);
// calculate the distance!
float x;
Vector2.Dot(ref toP, ref E, out x);
if (x <= 0.0f)
{
// x is outside the line segment, distance is from pt to ptA.
//dist = (pt - ptA).Length();
Vector2.Distance(ref point, ref ptA, out dist);
hitPt = ptA;
edgeD = 0f;
normal = n;
}
else if (x >= edgeLength)
{
// x is outside of the line segment, distance is from pt to ptB.
//dist = (pt - ptB).Length();
Vector2.Distance(ref point, ref ptB, out dist);
hitPt = ptB;
edgeD = 1f;
normal = n;
}
else
{
// point lies somewhere on the line segment.
Vector3 toP3 = new Vector3();
toP3.X = toP.X;
toP3.Y = toP.Y;
Vector3 E3 = new Vector3();
E3.X = E.X;
E3.Y = E.Y;
//dist = Math.Abs(Vector3.Cross(toP3, E3).Z);
Vector3.Cross(ref toP3, ref E3, out E3);
dist = Math.Abs(E3.Z);
hitPt.X = ptA.X + (E.X * x);
hitPt.Y = ptA.Y + (E.Y * x);
edgeD = x / edgeLength;
normal = n;
}
return dist;
}