Last active
May 24, 2023 18:57
-
-
Save audinue/f570ab40b0de37a8cd9d5ffb14ff1278 to your computer and use it in GitHub Desktop.
Closest 3D point on triangle. Expanded from SharpDX implementation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function closest (result, p, a, b, c) { | |
var px = p[0] | |
var py = p[1] | |
var pz = p[2] | |
var ax = a[0] | |
var ay = a[1] | |
var az = a[2] | |
var bx = b[0] | |
var by = b[1] | |
var bz = b[2] | |
var cx = c[0] | |
var cy = c[1] | |
var cz = c[2] | |
var abx = bx - ax | |
var aby = by - ay | |
var abz = bz - az | |
var acx = cx - ax | |
var acy = cy - ay | |
var acz = cz - az | |
var apx = px - ax | |
var apy = py - ay | |
var apz = pz - az | |
var d1 = abx * apx + aby * apy + abz * apz | |
var d2 = acx * apx + acy * apy + acz * apz | |
if (d1 <= 0 && d2 <= 0) { | |
result[0] = ax | |
result[1] = ay | |
result[2] = az | |
return | |
} | |
var bpx = px - bx | |
var bpy = py - by | |
var bpz = pz - bz | |
var d3 = abx * bpx + aby * bpy + abz * bpz | |
var d4 = acx * bpx + acy * bpy + acz * bpz | |
if (d3 >= 0 && d4 <= d3) { | |
result[0] = bx | |
result[1] = by | |
result[2] = bz | |
return | |
} | |
var vc = d1 * d4 - d3 * d2 | |
if (vc <= 0 && d1 >= 0 && d3 <= 0) { | |
var v = d1 / (d1 - d3) | |
result[0] = ax + abx * v | |
result[1] = ay + aby * v | |
result[2] = az + abz * v | |
return | |
} | |
var cpx = px - cx | |
var cpy = py - cy | |
var cpz = pz - cz | |
var d5 = abx * cpx + aby * cpy + abz * cpz | |
var d6 = acx * cpx + acy * cpy + acz * cpz | |
if (d6 >= 0 && d5 <= d6) { | |
result[0] = cx | |
result[1] = cy | |
result[2] = cz | |
return | |
} | |
var vb = d5 * d2 - d1 * d6 | |
if (vb <= 0 && d2 >= 0 && d6 <= 0) { | |
var w = d2 / (d2 - d6) | |
result[0] = ax + acx * w | |
result[1] = ay + acy * w | |
result[2] = az + acz * w | |
return | |
} | |
var va = d3 * d6 - d5 * d4 | |
if (va <= 0 && (d4 - d3) >= 0 && (d5 - d6) >= 0) { | |
var w = (d4 - d3) / ((d4 - d3) + (d5 - d6)) | |
result[0] = bx + (cx - bx) * w | |
result[1] = by + (cy - by) * w | |
result[2] = bz + (cz - bz) * w | |
return | |
} | |
var denom = 1 / (va + vb + vc) | |
var v2 = vb * denom | |
var w2 = vc * denom | |
result[0] = ax + abx * v2 + acx * w2 | |
result[1] = ay + aby * v2 + acy * w2 | |
result[2] = az + abz * v2 + acz * w2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment