Skip to content

Instantly share code, notes, and snippets.

@markandgo
Created November 17, 2012 00:53
Show Gist options
  • Save markandgo/4092294 to your computer and use it in GitHub Desktop.
Save markandgo/4092294 to your computer and use it in GitHub Desktop.
Generic raycasting through grid (Digital Differential Algorithm)
-- v1.0
local floor = math.floor
-- cell_width being the width of the cell along an axis e.g. x/y axis
local initRayData = function(cell_width,i,f)
local d = f-i
local cell_i = floor(i/cell_width)
local dRatio,Delta,Step,Start
if d > 0 then
Step = 1
Start = 1
else
Step = -1
Start = 0
end
-- zero hack for when 0/0
if d == 0 then
dRatio = math.huge
Delta = 0
else
dRatio = (cell_width*(cell_i+Start)-i)/d
Delta = cell_width/d * Step
end
return dRatio,Delta,Step,cell_i
end
local getState = function(width,height,x,y,x2,y2)
local s = {minRatio = 0}
s.dxRatio,s.xDelta,s.xStep,s.gx = initRayData(width,x,x2)
s.dyRatio,s.yDelta,s.yStep,s.gy = initRayData(height,y,y2)
return s
end
local next = function(s)
local gx,gy = s.gx,s.gy
-- if the next voxel is within range then go to the next voxel
if s.minRatio <= 1 then
if s.dxRatio < s.dyRatio then
s.minRatio= s.dxRatio
s.dxRatio = s.dxRatio + s.xDelta
s.gx = s.gx + s.xStep
else
s.minRatio= s.dyRatio
s.dyRatio = s.dyRatio + s.yDelta
s.gy = s.gy + s.yStep
end
return gx,gy
end
end
local iterate = function(width,height,x,y,x2,y2)
return next,getState(width,height,x,y,x2,y2)
end
return
{
next = next,
getState = getState,
iterate = iterate,
}
@markandgo
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment