v9.7.2: Ebonhold Database integration and core logic refinements
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
---@class RamerDouglasPeucker
|
||||
local RamerDouglasPeucker = QuestieLoader:CreateModule("RamerDouglasPeucker")
|
||||
|
||||
|
||||
-- code after this point is Ramer-Douglas-Peucker algorithm implemented by Eryn Lynn
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Eryn Lynn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE. ]]
|
||||
-- Implementation of the Ramer–Douglas–Peucker algorithm
|
||||
-- readme https://github.com/evaera/RobloxLuaAlgorithms#ramerdouglaspeuckerlua
|
||||
-- author: evaera
|
||||
|
||||
|
||||
local function getSqDist(p1, p2)
|
||||
local dx = p1[1] - p2[1]
|
||||
local dy = p1[2] - p2[2]
|
||||
|
||||
return dx * dx + dy * dy
|
||||
end
|
||||
|
||||
local function simplifyRadialDist(points, sqTolerance)
|
||||
local prevPoint = points[1]
|
||||
local newPoints = {prevPoint}
|
||||
local point
|
||||
|
||||
for i=2, #points do
|
||||
point = points[i]
|
||||
|
||||
if getSqDist(point, prevPoint) > sqTolerance then
|
||||
table.insert(newPoints, point)
|
||||
prevPoint = point
|
||||
end
|
||||
end
|
||||
|
||||
if prevPoint ~= point then
|
||||
table.insert(newPoints, point)
|
||||
end
|
||||
|
||||
return newPoints
|
||||
end
|
||||
|
||||
local function getSqSegDist(p, p1, p2)
|
||||
local x = p1[1]
|
||||
local y = p1[2]
|
||||
local dx = p2[1] - x
|
||||
local dy = p2[2] - y
|
||||
|
||||
if dx ~= 0 or dy ~= 0 then
|
||||
local t = ((p[1] - x) * dx + (p[2] - y) * dy) / (dx * dx + dy * dy)
|
||||
|
||||
if t > 1 then
|
||||
x = p2[1]
|
||||
y = p2[2]
|
||||
elseif t > 0 then
|
||||
x = x + dx * t
|
||||
y = y + dy * t
|
||||
end
|
||||
end
|
||||
|
||||
dx = p[1] - x
|
||||
dy = p[2] - y
|
||||
|
||||
return dx * dx + dy * dy
|
||||
end
|
||||
|
||||
local function simplifyDPStep(points, first, last, sqTolerance, simplified)
|
||||
local maxSqDist = sqTolerance
|
||||
local index
|
||||
|
||||
for i=first+1, last do
|
||||
local sqDist = getSqSegDist(points[i], points[first], points[last])
|
||||
|
||||
if sqDist > maxSqDist then
|
||||
index = i
|
||||
maxSqDist = sqDist
|
||||
end
|
||||
end
|
||||
|
||||
if maxSqDist > sqTolerance then
|
||||
if index - first > 1 then
|
||||
simplifyDPStep(points, first, index, sqTolerance, simplified)
|
||||
end
|
||||
|
||||
table.insert(simplified, points[index])
|
||||
|
||||
if last - index > 1 then
|
||||
simplifyDPStep(points, index, last, sqTolerance, simplified)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function simplifyDouglasPeucker(points, sqTolerance)
|
||||
local last = #points
|
||||
|
||||
local simplified={points[1]}
|
||||
simplifyDPStep(points, 1, last, sqTolerance, simplified)
|
||||
table.insert(simplified, points[last])
|
||||
|
||||
return simplified
|
||||
end
|
||||
|
||||
local _RamerDouglasPeucker = function(points, tolerance, highestQuality)
|
||||
if #points <= 2 then
|
||||
return points
|
||||
end
|
||||
|
||||
local sqTolerance = tolerance ~= nil and tolerance^2 or 1
|
||||
|
||||
points = highestQuality and points or simplifyRadialDist(points, sqTolerance)
|
||||
points = simplifyDouglasPeucker(points, sqTolerance)
|
||||
|
||||
return points
|
||||
end
|
||||
|
||||
setmetatable(RamerDouglasPeucker, { __call = function(_, ...) return _RamerDouglasPeucker(...) end})
|
||||
Reference in New Issue
Block a user