module Qwaiter 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