mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-24 22:52:24 +01:00
763ae3db8d
We need it to be 3D though.
We essentially just ported f51f153459/src/index.js
to Lua, as https://medium.com/geekculture/bresenhams-line-drawing-algorithm-2e0e953901b3 was WRONG as it didn't handle all edge cases and this one is much more optimised.
158 lines
3.8 KiB
Lua
158 lines
3.8 KiB
Lua
local Vector3 = dofile("worldeditadditions/utils/vector3.lua")
|
|
|
|
local function make_grid(size)
|
|
local grid = {}
|
|
|
|
for y=1,size.y do
|
|
for x=1,size.x do
|
|
grid[(size.x * y) + x] = 0
|
|
end
|
|
end
|
|
|
|
return {
|
|
size = size,
|
|
data = grid
|
|
}
|
|
end
|
|
|
|
local function index(grid, pos)
|
|
return (grid.size.x * pos.y) + pos.x
|
|
end
|
|
|
|
local function grid_to_string(grid)
|
|
local result = {}
|
|
for y=1,grid.size.y do
|
|
for x=1,grid.size.x do
|
|
local i = index(grid, Vector3.new(x, y))
|
|
if grid.data[i] == 0 then
|
|
table.insert(result, "#")
|
|
elseif grid.data[i] == 1 then
|
|
table.insert(result, " ")
|
|
elseif grid.data[i] < 10 then
|
|
table.insert(result, tostring(grid.data[i]))
|
|
else
|
|
table.insert(result, "?")
|
|
end
|
|
end
|
|
table.insert(result, "\n")
|
|
end
|
|
|
|
return table.concat(result, "")
|
|
end
|
|
|
|
--- Draws a line using Bresenham's algorithm in 2d.
|
|
-- Implemented ported from https://github.com/anushaihalapathirana/Bresenham-line-drawing-algorithm/blob/f51f153459a1656bfb1f433edc75e6644a052bb2/src/index.js
|
|
-- @param grid Grid The grid to draw on.
|
|
-- @param pos1 Vector3 The starting point of the line.
|
|
-- @param pos2 Vector3 The ending point of the line.
|
|
-- @param value number The number to fill in grid cells we draw in.
|
|
-- @returns void
|
|
local function draw_line_2d(grid, pos1, pos2, value)
|
|
if not value then value = 1 end
|
|
|
|
if pos1 == pos2 then
|
|
grid.data[index(grid, pos1)] = value
|
|
return
|
|
end
|
|
|
|
grid.data[index(grid, pos1)] = value -- plot pos1
|
|
local delta = pos2 - pos1
|
|
local absdelta = delta:abs()
|
|
local delta_error = (2 * absdelta.y) - absdelta.x -- d
|
|
if absdelta.x <= absdelta.y then delta_error = (2 * absdelta.x) - absdelta.y end
|
|
|
|
local pos_current = pos1:clone()
|
|
local steps = 0
|
|
|
|
local limit = absdelta.y
|
|
if absdelta.x > absdelta.y then limit = absdelta.x end
|
|
|
|
for _=1,limit do
|
|
local do_x = false
|
|
local do_y = false
|
|
if absdelta.x > absdelta.y then
|
|
do_x = true
|
|
if delta_error < 0 then
|
|
delta_error = delta_error + 2*absdelta.y
|
|
else
|
|
do_y = true
|
|
delta_error = delta_error + (2*absdelta.y - 2*absdelta.x)
|
|
end
|
|
else
|
|
do_y = true
|
|
if delta_error < 0 then
|
|
delta_error = delta_error + 2*absdelta.x
|
|
else
|
|
do_x = true
|
|
delta_error = delta_error + (2*absdelta.x) - (2*absdelta.y)
|
|
end
|
|
end
|
|
|
|
|
|
if do_x then
|
|
local acc = 1
|
|
if delta.x < 0 then acc = -1 end
|
|
pos_current.x = pos_current.x + acc
|
|
end
|
|
if do_y then
|
|
local acc = 1
|
|
if delta.y < 0 then acc = -1 end
|
|
pos_current.y = pos_current.y + acc
|
|
end
|
|
|
|
local i = index(grid, pos_current)
|
|
grid.data[i] = value
|
|
steps = steps + 1
|
|
end
|
|
end
|
|
|
|
local size = Vector3.new(120, 40)
|
|
local grid = make_grid(size)
|
|
|
|
|
|
|
|
-- draw_line_2d(grid, Vector3.new(10, 10), Vector3.new(40, 10))
|
|
-- draw_line_2d(grid, Vector3.new(70, 10), Vector3.new(70, 10))
|
|
draw_line_2d(grid, Vector3.new(75, 10), Vector3.new(75, 40))
|
|
draw_line_2d(grid, Vector3.new(80, 40), Vector3.new(80, 10))
|
|
|
|
-- local centre = Vector3.new(25, 25)
|
|
-- draw_line_2d(grid, centre, Vector3.new(0, 0))
|
|
-- draw_line_2d(grid, centre, Vector3.new(5, 0))
|
|
-- draw_line_2d(grid, centre, Vector3.new(10, 0))
|
|
-- draw_line_2d(grid, centre, Vector3.new(15, 0))
|
|
-- draw_line_2d(grid, centre, Vector3.new(20, 0))
|
|
-- draw_line_2d(grid, centre, Vector3.new(25, 0))
|
|
-- draw_line_2d(grid, centre, Vector3.new(30, 0), 3)
|
|
|
|
for i=1,9 do
|
|
print("LINE", i)
|
|
local pos1 = Vector3.new(
|
|
math.random(0, size.x),
|
|
math.random(0, size.y)
|
|
)
|
|
local pos2 = Vector3.new(
|
|
math.random(0, size.x),
|
|
math.random(0, size.y)
|
|
)
|
|
draw_line_2d(grid, pos1, pos2)
|
|
end
|
|
-- draw_line_2d(grid,
|
|
-- Vector3.new(3, 4),
|
|
-- Vector3.new(8, 9)
|
|
-- )
|
|
-- draw_line_2d(grid,
|
|
-- Vector3.new(10, 9),
|
|
-- Vector3.new(15, 4)
|
|
-- )
|
|
-- draw_line_2d(grid,
|
|
-- Vector3.new(20, 10),
|
|
-- Vector3.new(40, 20)
|
|
-- )
|
|
-- draw_line_2d(grid,
|
|
-- Vector3.new(10, 9),
|
|
-- Vector3.new(55, 4)
|
|
-- )
|
|
|
|
print(grid_to_string(grid))
|