Mathf.Lerp for integers
Unexpectedly for myself, I'm hung up on this issue. Suppose there is an array with a length of N elements. And we need to take an element from there, but not by index, but by value t = [0..1] (from 0 to 1 both inclusive). That is, the problem is reduced to a linear interpolation of the float value into the index of the array.
int index = (int) Mathf.Lerp(0, N, t);
But when t = 1
, then index = N
which is out of array's range.
We can fix this as follows:
int index = Mathf.Clamp((int) Mathf.Lerp(0, N, t), 0, N - 1);
or int index = (int) Mathf.Lerp(0, N, t - Mathf.Epsilon);
but i dont like the way it looks.
So the question is how to do this gracefully?
I would do as simple as this :
int index = $$anonymous$$athf.RoundToInt( t * ( N - 1 ) ) ;
Thanks for the answer, but this is not correct. The range of index 9 is less than that of the rest. For example, if t = 0.93
, then index = 8
.
If you have 9 elements in your array, and t = 0.93, then the output will be 7 (7.44 rounded down). Supposing t = 0.95, the output is 8, and you get the last element of your array.
What's wrong with this?
Here is a graphic showing the index according to t :
Answer by Hellium · Jul 18, 2018 at 02:31 PM
After our discussion in the comments, here is the formula that should work:
// Scaling by ( 1 - Mathf.Epsilon ) prevents N to be chosen when t == 1
int index = Mathf.FloorToInt( t * N * ( 1 - Mathf.Epsilon ) ) ;
And now here is exactly the problem that I described initially!
When t = 1
, then index = N
which is out of array's range.
P. S. You have one redundant closing parentheses in your answer.
Oh yes, you are right! I guess, you have no choice but scaling by ( 1 - $$anonymous$$athf.Epsilon ) :
int index = $$anonymous$$athf.FloorToInt( t * N * ( 1 - $$anonymous$$athf.Epsilon ) ) ;
I hoped there was a way to solve it more elegantly :)