-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
bresenham.lua
157 lines (135 loc) · 3.76 KB
/
bresenham.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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))