48 lines
1.4 KiB
Ruby
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
|