Étant donné un tableau de points x, y, comment trier les points de ce tableau dans le sens des aiguilles d'une montre (autour de leur point central moyen global)? Mon objectif est de passer les points à une fonction de création de ligne pour aboutir à quelque chose qui semble plutôt "solide", aussi convexe que possible sans intersection de lignes.
Pour ce que ça vaut, j'utilise Lua, mais n'importe quel pseudocode serait apprécié.
Mise à jour: Pour référence, voici le code Lua basé sur l'excellente réponse de Ciamej (ignorez mon préfixe "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)
qui itère sur les indices et les valeurs de tbl de 1 à #tbl. Donc, pour le calcul de la somme, vous pouvez le faire, ce que la plupart des gens trouvent plus propre:for _, p in ipairs(points) do pointsSum.x = pointsSum.x + p.x; pointsSum.y = pointsSum.y + p.y end
ipairs
est nettement plus lent que la boucle for numérique.