Dato un array di punti x, y, come posso ordinare i punti di questo array in senso orario (attorno al loro punto centrale medio complessivo)? Il mio obiettivo è passare i punti a una funzione di creazione di linee per finire con qualcosa che sembra piuttosto "solido", il più convesso possibile senza linee che si intersecano.
Per quello che vale, sto usando Lua, ma qualsiasi pseudocodice sarebbe apprezzato.
Aggiornamento: per riferimento, questo è il codice Lua basato sulla risposta eccellente di Ciamej (ignora il mio prefisso "app"):
function appSortPointsClockwise(points)
local centerPoint = appGetCenterPointOfPoints(points)
app.pointsCenterPoint = centerPoint
table.sort(points, appGetIsLess)
return points
end
function appGetIsLess(a, b)
local center = app.pointsCenterPoint
if a.x >= 0 and b.x < 0 then return true
elseif a.x == 0 and b.x == 0 then return a.y > b.y
end
local det = (a.x - center.x) * (b.y - center.y) - (b.x - center.x) * (a.y - center.y)
if det < 0 then return true
elseif det > 0 then return false
end
local d1 = (a.x - center.x) * (a.x - center.x) + (a.y - center.y) * (a.y - center.y)
local d2 = (b.x - center.x) * (b.x - center.x) + (b.y - center.y) * (b.y - center.y)
return d1 > d2
end
function appGetCenterPointOfPoints(points)
local pointsSum = {x = 0, y = 0}
for i = 1, #points do pointsSum.x = pointsSum.x + points[i].x; pointsSum.y = pointsSum.y + points[i].y end
return {x = pointsSum.x / #points, y = pointsSum.y / #points}
end
ipairs(tbl)
che scorre sugli indici e sui valori di tbl da 1 a #tbl. Quindi, per il calcolo della somma, puoi farlo, che la maggior parte delle persone sembra più pulita:for _, p in ipairs(points) do pointsSum.x = pointsSum.x + p.x; pointsSum.y = pointsSum.y + p.y end
ipairs
è significativamente più lenta di quella numerica per il ciclo.