many worldgen mods and gonna try technic now
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
-- algorithms taken from https://gist.github.com/reciprocum/4e3599a9563ec83ba2a63f5a6cdd39eb
|
||||
|
||||
local dot = function(a, b)
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z
|
||||
end
|
||||
|
||||
local modulus = function(v)
|
||||
return math.sqrt(dot(v,v))
|
||||
end
|
||||
|
||||
local cross = function(a, b)
|
||||
return {x= a.y * b.z - a.z * b.y,
|
||||
y= a.z * b.x - a.x * b.z,
|
||||
z= a.x * b.y - a.y * b.x}
|
||||
end
|
||||
|
||||
-- TODO: add bounding box tests to early-out on distant segments
|
||||
|
||||
-- Calculates the distance from a point to a line segment.
|
||||
-- v - the point
|
||||
-- a - start of line segment
|
||||
-- b - end of line segment
|
||||
|
||||
mapgen_helper.distance_to_segment = function(v, a, b)
|
||||
local ab = vector.subtract(b, a)
|
||||
local av = vector.subtract(v, a)
|
||||
|
||||
if dot(av, ab) <= 0.0 then -- Point is lagging behind start of the segment, so perpendicular distance is not viable.
|
||||
return modulus(av) -- Use distance to start of segment instead.
|
||||
end
|
||||
|
||||
local bv = vector.subtract(v, b)
|
||||
|
||||
if dot(bv, ab) >= 0.0 then -- Point is advanced past the end of the segment, so perpendicular distance is not viable.
|
||||
return modulus(bv) -- Use distance to end of the segment instead.
|
||||
end
|
||||
|
||||
return modulus( cross(ab, av )) / modulus(ab) -- Perpendicular distance of point to segment.
|
||||
end
|
||||
|
||||
-- Calculates the euclidean distance from a point to a line segmented path.
|
||||
-- v - the point from with the distance is measured
|
||||
-- path - the array of points which, when sequentialy joined by line segments, form a path
|
||||
-- returns the distance from v to the closest of the path forming line segments
|
||||
|
||||
mapgen_helper.distance_to_path = function(v, path)
|
||||
local minimum_distance = 2^32 -- Should be big enough for any practical minetest needs
|
||||
for i = 2, table.getn(path) do
|
||||
local distance = mapgen_helper.distance_to_segment(path[i-1], path[i])
|
||||
if (distance < minimum_distance) then
|
||||
minimum_distance = distance
|
||||
end
|
||||
end
|
||||
return minimum_distance
|
||||
end
|
||||
|
||||
|
||||
-- For digging out straight lines
|
||||
|
||||
local dist_sq = function(x1, y1, z1, x2, y2, z2)
|
||||
return (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2
|
||||
end
|
||||
local constrain = function(n, min_n, max_n)
|
||||
if n < min_n then return min_n
|
||||
elseif n > max_n then return max_n
|
||||
else return n end
|
||||
end
|
||||
local dist_to_segment_squared = function(px, py, pz, lx1, ly1, lz1, lx2, ly2, lz2)
|
||||
local line_dist = dist_sq(lx1, ly1, lz1, lx2, ly2, lz2)
|
||||
if (line_dist == 0) then
|
||||
return dist_sq(px, py, pz, lx1, ly1, lz1)
|
||||
end
|
||||
local t = ((px - lx1) * (lx2 - lx1) + (py - ly1) * (ly2 - ly1) + (pz - lz1) * (lz2 - lz1)) / line_dist
|
||||
t = constrain(t, 0, 1)
|
||||
return dist_sq(px, py, pz, lx1 + t * (lx2 - lx1), ly1 + t * (ly2 - ly1), lz1 + t * (lz2 - lz1))
|
||||
end
|
||||
Reference in New Issue
Block a user