Skip to content

Instantly share code, notes, and snippets.

@EngineerSmith
Created May 14, 2020 14:48
Show Gist options
  • Save EngineerSmith/b5542fcbdac598ec822241f8a28af47b to your computer and use it in GitHub Desktop.
Save EngineerSmith/b5542fcbdac598ec822241f8a28af47b to your computer and use it in GitHub Desktop.
local maths = {}
function maths.cross(ux, uy, uz, vx, vy, vz)
local nx = (uy*vz) - (uz*vy)
local ny = (uz*vx) - (ux*vz)
local nz = (ux*vy) - (uy*vx)
return nx, ny, nz
end
function maths.dot(ux, uy, uz, vx, vy, vz)
return ux*vx + uy*vy + uz*vz
end
-- line = {{x,y,z},{x,y,z}} -- Origin, Direction
-- triangle = {{x,y,z},{x,y,z},{x,y,z}} -- Point1, Point2, Point3
function maths.intersectTriangle(line, triangle)
local l1 = line[1] -- Origin
local l2 = line[2] -- Direction
local p1 = triangle[1]
local p2 = triangle[2]
local p3 = triangle[3]
local ux = p2[1] - p1[1]
local uy = p2[2] - p1[2]
local uz = p2[3] - p1[3]
local vx = p3[1] - p1[1]
local vy = p3[2] - p1[2]
local vz = p3[3] - p1[3]
local hx, hy, hz = maths.cross(l2[1], l2[2], l2[3], vx, vy, vz)
local det = maths.dot(ux, uy, uz, hx, hy, hz)
if det > -1e-6 and det < 1e-6 then
return false
end
local invdet = 1.0/det
local u = maths.dot(l2[1], l2[2], l2[3], hx, hy, hz) * invdet
if u < 0.0 or u > 1.0 then
return false
end
local sx = l1[1] - p1[1]
local sy = l1[2] - p1[2]
local sz = l1[3] - p1[3]
local qx, qy, qz = maths.cross(sx, sy, sz, ux, uy, uz)
local v = maths.dot(l2[1], l2[2], l2[3], qx, qy, qz) * invdet
if v < 0.0 or u + v > 1.0 then
return false
end
local t = maths.dot(vx, vy, vz, qx, qy, qz) * invdet
if t > 1e-6 then
-- intersection point
local ix, iy, iz = l1[1] + l2[1] * t, l1[2] + l2[2] * t, l1[3] + l2[3] * t
return true, ix, iy, iz
end
return false -- line, but not ray intersection
end
return maths
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment