class Draught::SheetBuilder

Attributes

boxes[R]
max_height[R]
max_width[R]
outer_gap[R]

Public Class Methods

new(opts = {}) click to toggle source
# File lib/draught/sheet_builder.rb, line 12
def initialize(opts = {})
  @max_width = opts.fetch(:max_width)
  @max_height = opts.fetch(:max_height)
  @outer_gap = opts.fetch(:outer_gap, 0)
  @boxes = opts.fetch(:boxes)
end
sheet(args) click to toggle source
# File lib/draught/sheet_builder.rb, line 8
def self.sheet(args)
  new(args).sheet
end

Public Instance Methods

==(other) click to toggle source
# File lib/draught/sheet_builder.rb, line 29
def ==(other)
  comparison_args.inject(true) { |ok, meth_name|
    send(meth_name) == other.send(meth_name) && ok
  }
end
sheet() click to toggle source
# File lib/draught/sheet_builder.rb, line 19
def sheet
  containers = nested
  Sheet.new({
    lower_left: Point::ZERO,
    containers: containers,
    width: width(containers),
    height: height(containers)
  })
end

Private Instance Methods

comparison_args() click to toggle source
# File lib/draught/sheet_builder.rb, line 37
def comparison_args
  [:max_width, :max_height, :outer_gap, :boxes]
end
containers() click to toggle source
# File lib/draught/sheet_builder.rb, line 41
def containers
  @containers ||= nested
end
edge_length(boxes, min_method, max_method) click to toggle source
# File lib/draught/sheet_builder.rb, line 68
def edge_length(boxes, min_method, max_method)
  min = boxes.map(&min_method).min
  max = boxes.map(&max_method).max
  (max - min) + (2 * outer_gap)
end
find_placement_point(box, placed_boxes) click to toggle source
# File lib/draught/sheet_builder.rb, line 74
def find_placement_point(box, placed_boxes)
  return Point::ZERO if placeable_at_location?(box, Point::ZERO, placed_boxes)
  placement_after_a_box(box, placed_boxes) || placement_above_a_box(box, placed_boxes)
end
fits?(box) click to toggle source
# File lib/draught/sheet_builder.rb, line 126
def fits?(box)
  x = 0..usable_width
  y = 0..usable_height
  box.corners.all? { |point| x.include?(point.x) && y.include?(point.y) }
end
height(boxes) click to toggle source
# File lib/draught/sheet_builder.rb, line 64
def height(boxes)
  edge_length(boxes, :bottom_edge, :top_edge)
end
nested() click to toggle source
# File lib/draught/sheet_builder.rb, line 45
def nested
  full = false
  nested_boxes = []
  boxes.cycle do |box|
    break if full
    placement_point = find_placement_point(box, nested_boxes)
    if placement_point
      nested_boxes << box.move_to(placement_point)
    else
      full = true
    end
  end
  nested_boxes.map { |box| box.translate(origin_offset) }
end
no_overlaps?(box, placed_boxes) click to toggle source
# File lib/draught/sheet_builder.rb, line 122
def no_overlaps?(box, placed_boxes)
  placed_boxes.none? { |placed_box| box.overlaps?(placed_box) }
end
offset(box, reference_box, reference_point_method) click to toggle source
# File lib/draught/sheet_builder.rb, line 98
def offset(box, reference_box, reference_point_method)
  gap = [box.min_gap, reference_box.min_gap].max
  offset_point(gap, reference_box, reference_point_method)
end
offset_point(gap, box, reference_point_method) click to toggle source
# File lib/draught/sheet_builder.rb, line 103
def offset_point(gap, box, reference_point_method)
  offset = offset_translation(gap, reference_point_method)
  box.send(reference_point_method).translate(offset)
end
offset_translation(gap, reference_point_method) click to toggle source
# File lib/draught/sheet_builder.rb, line 108
def offset_translation(gap, reference_point_method)
  case reference_point_method
  when :lower_right
    Vector.new(gap, 0)
  when :upper_left
    Vector.new(0, gap)
  end
end
origin_offset() click to toggle source
# File lib/draught/sheet_builder.rb, line 140
def origin_offset
  Vector.new(outer_gap, outer_gap)
end
placeable_at_location?(box, placement_point, placed_boxes) click to toggle source
# File lib/draught/sheet_builder.rb, line 117
def placeable_at_location?(box, placement_point, placed_boxes)
  box_to_place = box.move_to(placement_point)
  no_overlaps?(box_to_place, placed_boxes) && fits?(box_to_place)
end
placement_above_a_box(box, placed_boxes) click to toggle source
# File lib/draught/sheet_builder.rb, line 83
def placement_above_a_box(box, placed_boxes)
  placement_around_a_box(box, placed_boxes, :upper_left)
end
placement_after_a_box(box, placed_boxes) click to toggle source
# File lib/draught/sheet_builder.rb, line 79
def placement_after_a_box(box, placed_boxes)
  placement_around_a_box(box, placed_boxes, :lower_right)
end
placement_around_a_box(box, placed_boxes, reference_point_method) click to toggle source
# File lib/draught/sheet_builder.rb, line 87
def placement_around_a_box(box, placed_boxes, reference_point_method)
  reference_box = placed_boxes.find { |placed_box|
    point = offset(box, placed_box, reference_point_method)
    placeable_at_location?(box, point, placed_boxes)
  }
  if reference_box
    return offset(box, reference_box, reference_point_method)
  end
  false
end
usable_height() click to toggle source
# File lib/draught/sheet_builder.rb, line 136
def usable_height
  @usable_height ||= max_height - (2 * outer_gap)
end
usable_width() click to toggle source
# File lib/draught/sheet_builder.rb, line 132
def usable_width
  @usable_width ||= max_width - (2 * outer_gap)
end
width(boxes) click to toggle source
# File lib/draught/sheet_builder.rb, line 60
def width(boxes)
  edge_length(boxes, :left_edge, :right_edge)
end