Bir x, y noktası dizisi verildiğinde, bu dizinin noktalarını saat yönünde (genel ortalama merkez noktalarının çevresinde) nasıl sıralayabilirim? Amacım, çizgileri bir çizgi oluşturma işlevine geçirerek oldukça "katı" görünen bir şeyle sonuçlanmak ve mümkün olduğunca dışbükey çizgiler olmadan kesmektir.
Değer için, Lua kullanıyorum, ancak herhangi bir sahte kod takdir edilecektir.
Güncelleme: Referans için, bu Ciamej'in mükemmel cevabına dayanan Lua kodu (benim "uygulama" önekimi yoksay)
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)
indeksleri ve değerleri üzerinde 1'den #tbl'e kadar yinelenen yerleşik bir işleve sahiptir . Toplam hesaplama için, çoğu insanın daha temiz göründüğü bunu yapabilirsiniz:for _, p in ipairs(points) do pointsSum.x = pointsSum.x + p.x; pointsSum.y = pointsSum.y + p.y end
ipairs
döngü için sayısaldan önemli ölçüde yavaştır.