Files
mozo-backend/lib/mozo/distribution.rb
T
2025-09-20 17:35:58 -05:00

48 lines
1.4 KiB
Ruby

module Mozo
module Distribution
module DistributionMethods
def epsilon
@@epsilon ||= (10 ** -(Float::DIG - 1)).to_f
end
##
# Distribute a section of width w and height h in a length and a width scale
# that makes n tables fit.
# distribute_lattice 10, 10, 3 #=> [5.0, 5.0]
# distribute_lattice 10, 10, 4 #=> [5.0, 5.0]
##
def distribute_lattice(w, h, n)
w, h = w.to_f, h.to_f
area = w*h
l = Math.sqrt(area.to_f/n)
nx = w/l
ny = h/l
while (w/l + epsilon).floor * (h/l + epsilon).floor < n
tx = w/l
ty = h/l
# The biggest remainder is closest to a fitting option
# Just add one if no remainder wins and it still is not enough
if tx.remainder(1) < epsilon && ty.remainder(1) < epsilon
# Both divide, but there is no solution yet. Just add one
l = [w/(tx + 1).round, h/(ty + 1).round].max
nx = tx.ceil
ny = ny.ceil
elsif tx.remainder(1) > ty.remainder(1)
nx = tx.ceil
ny = (n.to_f/nx).ceil
l = w/nx
else
ny = ty.ceil
nx = (n.to_f/ny).ceil
l = h/ny
end
end
[w/nx, h/ny]
end
end
include DistributionMethods
extend DistributionMethods
end
end