add get max coord and rayIter and improve fine line

This commit is contained in:
HybridDog 2016-04-23 11:09:10 +02:00
parent 934714fb48
commit 83ff39b66a

@ -97,36 +97,51 @@ local function return_line(pos, dir, range) --range ~= length
return tab return tab
end end
local function table_contains2(t, v) function funcs.rayIter(pos, dir)
for i = #t, 1, -1 do -- make a table of possible movements
if t[i] == v then local step = {}
return true for i in pairs(pos) do
local v = math.sign(dir[i])
if v ~= 0 then
step[i] = v
end end
end end
return false
end
local function return_fine_line(pos, dir, range, scale) local p
local ps1 = return_line(vector.round(vector.multiply(pos, scale)), dir, range*scale) return function()
local ps2 = {} if not p then
local ps2_num = 1 -- avoid skipping the first position
for _,p1 in ipairs(ps1) do p = vector.round(pos)
local p2 = vector.round(vector.divide(p1, scale)) return vector.new(p)
if not table_contains2(ps2, p2) then
ps2[ps2_num] = p2
ps2_num = ps2_num+1
end end
-- find the position which has the smallest distance to the line
local choose = {}
local choosefit = vector.new()
for i in pairs(step) do
choose[i] = vector.new(p)
choose[i][i] = choose[i][i] + step[i]
choosefit[i] = vector.scalar(vector.normalize(vector.subtract(choose[i], pos)), dir)
end
p = choose[vector.get_max_coord(choosefit)]
return vector.new(p)
end end
return ps2
end end
function funcs.fine_line(pos, dir, range, scale) function funcs.fine_line(pos, dir, range)
--assert_vector(pos)
if not range then --dir = pos2 if not range then --dir = pos2
dir = vector.direction(pos, dir) dir, range = vector.direction(pos, dir), vector.distance(pos, dir)
range = vector.distance(pos, dir)
end end
return return_fine_line(pos, dir, range, scale) local result,n = {},1
for p in vector.rayIter(pos, dir) do
if vector.distance(p, pos) > range then
break
end
result[n] = p
n = n+1
end
return result
end end
function funcs.line(pos, dir, range, alt) function funcs.line(pos, dir, range, alt)
@ -137,9 +152,9 @@ function funcs.line(pos, dir, range, alt)
end end
return return_line(pos, dir, range) return return_line(pos, dir, range)
end end
if range then --dir = pos2 if range then
dir = vector.round(vector.multiply(dir, range)) dir = vector.round(vector.multiply(dir, range))
else else --dir = pos2
dir = vector.subtract(dir, pos) dir = vector.subtract(dir, pos)
end end
local line,n = {},1 local line,n = {},1
@ -699,6 +714,19 @@ function funcs.unpack(pos)
return pos.z, pos.y, pos.x return pos.z, pos.y, pos.x
end end
function funcs.get_max_coord(vec)
if vec.x < vec.y then
if vec.y < vec.z then
return "z"
end
return "y"
end
if vec.x < vec.z then
return "z"
end
return "x"
end
function funcs.get_max_coords(pos) function funcs.get_max_coords(pos)
if pos.x < pos.y then if pos.x < pos.y then
if pos.y < pos.z then if pos.y < pos.z then