///distance_from_triangle(px, py, pz, x1, y1, z1, x2, y2, z2, x3, y3, z3)
var
px = argument0, py = argument1, pz = argument2,
x1 = argument3, y1 = argument4, z1 = argument5,
x2 = argument6, y2 = argument7, z2 = argument8,
x3 = argument9, y3 = argument10, z3 = argument11,
cx, cy, cz, nx, ny, nz, vx, vy, vz, ex, ey, ez, d;
//First get the triangle's normal
//Edge vectors
var
v12x = x2 - x1,
v12y = y2 - y1,
v12z = z2 - z1,
v13x = x3 - x1,
v13y = y3 - y1,
v13z = z3 - z1;
//Cross product
cx = v12y * v13z - v12z * v13y
cy = v12z * v13x - v12x * v13z
cz = v12x * v13y - v12y * v13x
//Normalize the cross product
d = 1 / point_distance_3d(0, 0, 0, cx, cy, cz)
nx = cx * d
ny = cy * d
nz = cz * d
//Create temp triangles from the point to each edge
//and check that the cross products are all facing towards the main triangle \ facing in the opposite direction to the main triangle's normal
//point to edge1
vx = px - x1
vy = py - y1
vz = pz - z1
ex = x2 - x1
ey = y2 - y1
ez = z2 - z1
if dot_product_3d_normalised(vz * ey - vy * ez, vx * ez - vz * ex, vy * ex - vx * ey, nx, ny, nz) <= 0
{
//To get the nearest point on the edge:
//Get the dot product of the edge vector and the vector to the first vertex of the edge
//Divide it by the length of the edge vector
//Clamp the result to (0, 1)
//Then lerp from v1 to v2 using this ratio
d = clamp(dot_product_3d(ex, ey, ez, vx, vy, vz) / point_distance_3d(0, 0, 0, ex, ey, ez), 0, 1)
ex = x1 + (ex * d)
ey = y1 + (ey * d)
ez = z1 + (ez * d)
return point_distance_3d(px, py, pz, ex, ey, ez)
}
//point to edge2
vx = px - x2
vy = py - y2
vz = pz - z2
ex = x3 - x2
ey = y3 - y2
ez = z3 - z2
if dot_product_3d_normalised(vz * ey - vy * ez, vx * ez - vz * ex, vy * ex - vx * ey, nx, ny, nz) <= 0
{
d = clamp(dot_product_3d(ex, ey, ez, vx, vy, vz) / point_distance_3d(0, 0, 0, ex, ey, ez), 0, 1)
ex = x2 + (ex * d)
ey = y2 + (ey * d)
ez = z2 + (ez * d)
return point_distance_3d(px, py, pz, ex, ey, ez)
}
//point to edge3
vx = px - x3
vy = py - y3
vz = pz - z3
ex = x1 - x3
ey = y1 - y3
ez = z1 - z3
if dot_product_3d_normalised(vz * ey - vy * ez, vx * ez - vz * ex, vy * ex - vx * ey, nx, ny, nz) <= 0
{
d = clamp(dot_product_3d(ex, ey, ez, vx, vy, vz) / point_distance_3d(0, 0, 0, ex, ey, ez), 0, 1)
ex = x3 + (ex * d)
ey = y3 + (ey * d)
ez = z3 + (ez * d)
return point_distance_3d(px, py, pz, ex, ey, ez)
}
//If not outside, the distance is the dot product of the triangle's normal and the vector from the point to one of the vertices
return abs(dot_product(nx, ny, nz, vx, vy, vz))