Well there’s one problem with that, we don’t know if the 3 points are in line with each other. And what do we do if they aren’t in line with each other?
Lets call the 3rd point C, so in the image above, the ? is C.
So, one way we can do this is that we just assume the person calling the method did their best effort to have the 3 points on the same line. And what we will do is project C on A->B to ensure we only measure it in that space. So if they pass in a C that is far away from A and B and no where on the line defined by AB… then we’ll only measure the percentage along AB.
This is because a dot product is a scalar projection. It measures the length of one vector along the other (with its scale intact that is). If the other is a unit vector though, then it’s the absolute length of one on the other. It’s like if you said AB was an axis, how far along the axis are we. If that axis was say the x-axis, it’s how far along the x-axis we are.
So with that assumption we will dot AC on a unit vector in the direction of AB, and divide by |AB| (magnitude). Which will give us the percentage along AB that AC is.
public static float GetPercentageAlong(Vector3 a, Vector3 b, Vector3 c)
{
var ab = b - a;
var ac = c - a;
return Vector3.Dot(ac, ab.normalized) / ab.magnitude;
}
Note though, we could do some simplification here. Dot product is defined as:
A dot B = (Ai * Bi + Aj * Bj + Ak * Bk)
[where i, j, and k, are the 3 parts of the vector x, y, and z respectively]
And that normalized would just make it:
(Ai * Bi / |B| + Aj * Bj / |B| + Ak * Bk / |B|) / |B|
And if we distribute that in we get:
(Ai * Bi + Aj * Bj + Ak * Bk) / |B|^2
We can get rid of that square root for magnitude now!
public static float GetPercentageAlong(Vector3 a, Vector3 b, Vector3 c)
{
var ab = b - a;
var ac = c - a;
return Vector3.Dot(ac, ab) / ab.sqrMagnitude;
}