InverseLerp for vector3
Hi
I am currently working on a 3D slider that will be placed inside the game world itself. I am wondering if there were a method similar to
public static float InverseLerp(float a, float b, float value);
but for vectors specifically for Vector3. I have sort of a work around. The sliders that i currently have placed are all working parallel the world unity axis, Vector.up, right and forward. The solution that i have right now for world axis sliders output the slider value like so:
public float SliderOutput{
get{
switch (RotationAxisChoice) {
case Axis.X:
return _sliderOutput = Mathf.InverseLerp(_lowerLimit.x, _opperLimit.x, _currentSlidePos.x);
case Axis.Y:
return _sliderOutput = Mathf.InverseLerp(_lowerLimit.y, _opperLimit.y, _currentSlidePos.y);
case Axis.Z:
return _sliderOutput = Mathf.InverseLerp(_lowerLimit.z, _opperLimit.z, _currentSlidePos.z);
}
return 0f;
}
}
this should work for the special case that the slider is perfectly aligned with the world axis, but i would like to do a generic solution that can have the slider orientated in any direction. And also get rid of the switch statement
Answer by Baertidaer · Nov 22, 2016 at 04:08 AM
I had the same problem and stumbled upon your question.
This works as a generic solution:
public static float InverseLerp(Vector3 a, Vector3 b, Vector3 value)
{
Vector3 AB = b - a;
Vector3 AV = value - a;
return Vector3.Dot(AV, AB) / Vector3.Dot(AB, AB);
}
You can of course Mathf.Clamp01()
the output if you want to.
This works in other dimensions too, just change Vector3 to Vector2.
Are you sure that Vector3.Dot(AB, AB) doesn't return zero? I really need to try this out!
If it does return 0 its because the length of AB is 0, the dot product of a vector with it self is equal to the magnitude squared: dot(a,a) = a.x*a.x + a.y *a.y +a.z*a.z
While I was waiting for your answer I've taked a look at the scripting API and I made a few calculations, and you're right. Good job.
So if A is equal to (0, 0, 0), B is equal to (2, 2, 0) and V is equal to (0, 2, 0), the function will return 0.5, so it does simply perfect.
I guess if V is "under" A the value will be less than 0, while if V is "above" B the value will be greater than 1.
Thanks @Baertidaer, that's a great solution!
I'm wondering what happens if value is not in the same plane (line in 2D) a and b define, does it still return a value that makes sense?
EDIT1: never $$anonymous$$d, I just did some tests on paper and it makes sense. It basically takes the perpendicular projection of value onto the AB plane (line in 2D). You could also say it ignores the coordinate which does not fit into the AB system.