module Hexagonly::Hexagon::Methods::ClassMethods

Public Instance Methods

pack(points, hex_size, params = {}) click to toggle source

Starting from the north-east corner of the given Points array and going east, then repeating for every other row to the south, the method generates an array of hexagons. If params is true, every hexagon created on the way grabs all the points contained within.

@param points [Array<Hexagonly::Point>] the boundries for the generated hexagons

or an Array of points that will be "grabbed" by the generated hexagons 
(see @params[:grap_points])

@param hex_size [Float] the size of the generated hexagons (width / 2) @param [Hash] params additional parameters @option params [false, true] :grab_points whether to “grab” points -

stores included points unter hex#collected_points and excluded points
under hex#rejected_points

@option params [false, true] :reject_empty when :grab_points is enabled

settings this option to true removes empty hexagons from the results

@option params [Class] :hexagon_class the class used to instanciate new hexagons @option params [Class] :point_class the class used to instanciate hexagon center points

@return [Array<Hexagonly::Hexagon] an array of hexagons

# File lib/hexagonly/hexagon.rb, line 53
def pack(points, hex_size, params = {})
  return [] if points.nil? || points.empty? || points.size < 2

  hexagons = []
  space = Hexagonly::Space.new(points)

  h_hexagon_count = ((space.east.x_coord - space.west.x_coord) / (hex_size * 1.5)).abs.ceil
  v_hexagon_count = ((space.north.y_coord - space.south.y_coord) / (hex_size * Math.cos(Math::PI / 6) * 2.0)).abs.ceil + 1

  point_class = params.fetch(:point_class, Hexagonly::Point)
  hexagon_class = params.fetch(:hexagon_class, Hexagonly::Hexagon)
  grab_points = params.fetch(:grab_points, false)
  reject_empty = params.fetch(:reject_empty, false)

  north_west = point_class.new.tap{ |p| p.set_coords(space.west.x_coord, space.north.y_coord) }
  hexagons << hex = hexagon_class.new.tap{ |h| h.setup_hex(north_west, hex_size); h.grab(points) if grab_points }
  v_hexagon_count.times do |i|
    first_hex = hex
    h_hexagon_count.times do |j|
      if j % 2 == 0
        hexagons << hex = hex.north_east_hexagon(params)
      else
        hexagons << hex = hex.south_east_hexagon(params)
      end
    end

    hexagons << hex = first_hex.south_hexagon(params) if i < v_hexagon_count - 1
  end

  if grab_points && reject_empty
    hexagons.reject!{ |hex| hex.collected_points.empty? }
  end

  hexagons
end