(point, corners)
| 30 | // based on https://iquilezles.org/articles/ibilinear/ |
| 31 | // adapted by Magnogen https://magnogen.net/ |
| 32 | export const ibilerp = (point, corners) => { |
| 33 | const p = point; |
| 34 | const [a, b, d, c] = corners; |
| 35 | |
| 36 | const e = subtractVector(b, a); |
| 37 | const f = subtractVector(d, a); |
| 38 | const g = addVector(subtractVector(a, b), subtractVector(c, d)); |
| 39 | const h = subtractVector(p, a); |
| 40 | |
| 41 | const k2 = crossProductVector(g, f); |
| 42 | const k1 = crossProductVector(e, f) + crossProductVector(h, g); |
| 43 | const k0 = crossProductVector(h, e); |
| 44 | |
| 45 | // If edges are parallel, this is a linear equation |
| 46 | if (Math.abs(k2) < 0.0001) { |
| 47 | const x = (h[0] * k1 + f[0] * k0) / (e[0] * k1 - g[0] * k0); |
| 48 | const y = -k0 / k1; |
| 49 | return [x, y]; |
| 50 | } |
| 51 | |
| 52 | // Otherwise, it's a quadratic |
| 53 | let w = k1 * k1 - 4 * k0 * k2; |
| 54 | w = Math.sqrt(w); |
| 55 | |
| 56 | const ik2 = 0.5 / k2; |
| 57 | let v = (-k1 - w) * ik2; |
| 58 | let u = (h[0] - f[0] * v) / (e[0] + g[0] * v); |
| 59 | |
| 60 | if (u < 0.0 || u > 1.0 || v < 0.0 || v > 1.0) { |
| 61 | v = (-k1 + w) * ik2; |
| 62 | u = (h[0] - f[0] * v) / (e[0] + g[0] * v); |
| 63 | } |
| 64 | |
| 65 | return [u, v]; |
| 66 | }; |
no test coverage detected