Performs a linear interpolation using a table of fixed points to create an effective piecewise f(x) = y function. @param x The x value. @param xyArray Array of points in [[x0,y0], ... [xN, yN]] format @return f(x) = y
(int x, int[][] xyArray)
| 271 | * @return f(x) = y |
| 272 | */ |
| 273 | public static int lerp(int x, int[][] xyArray) { |
| 274 | try { |
| 275 | if (x <= xyArray[0][0]){ // Clamp to first point |
| 276 | return xyArray[0][1]; |
| 277 | } else if (x >= xyArray[xyArray.length-1][0]) { // Clamp to last point |
| 278 | return xyArray[xyArray.length-1][1]; |
| 279 | } |
| 280 | // At this point we're guaranteed to have two lerp points, and pity be somewhere between them. |
| 281 | for (int i=0; i < xyArray.length-1; i++) { |
| 282 | if (x == xyArray[i+1][0]) { |
| 283 | return xyArray[i+1][1]; |
| 284 | } |
| 285 | if (x < xyArray[i+1][0]) { |
| 286 | // We are between [i] and [i+1], interpolation time! |
| 287 | // Using floats would be slightly cleaner but we can just as easily use ints if we're careful with order of operations. |
| 288 | int position = x - xyArray[i][0]; |
| 289 | int fullDist = xyArray[i+1][0] - xyArray[i][0]; |
| 290 | int prevValue = xyArray[i][1]; |
| 291 | int fullDelta = xyArray[i+1][1] - prevValue; |
| 292 | return prevValue + ( (position * fullDelta) / fullDist ); |
| 293 | } |
| 294 | } |
| 295 | } catch (IndexOutOfBoundsException e) { |
| 296 | Grasscutter.getLogger().error("Malformed lerp point array. Must be of form [[x0, y0], ..., [xN, yN]]."); |
| 297 | } |
| 298 | return 0; |
| 299 | } |
| 300 | |
| 301 | /** |
| 302 | * Checks if an int is in an int[] |
no test coverage detected