class Qrio::FinderPatternSlice

QR codes have a finder pattern in three corners. any horizontal or vertical slice through the center square will be a band of: black, white, black, white, black, with widths matching ratio: 1, 1, 3, 1, 1. According to spec, the tolerance should be +/- 0.5.

Constants

ENDPOINT_TOLERANCE
LENGTH_TOLERANCE
OFFSET_TOLERANCE
ONE
THREE
WIDTH_TOLERANCE

Attributes

neighbors[RW]
offset[R]
origin[R]
terminus[R]

Public Class Methods

build_matching(offset, origin, widths, direction) click to toggle source

given a width buffer extracted from a given coordinate, test for ratio matching. if it matches, return a match object of the appropriate orientation

# File lib/qrio/finder_pattern_slice.rb, line 49
def build_matching(offset, origin, widths, direction)
  return nil unless matches_ratio?(widths)

  match_class = direction == :horizontal ? HorizontalMatch : VerticalMatch
  terminus = origin + widths.inject(0){|s,w| s + w } - 1

  match_class.build(offset, origin, terminus)
end
matches_ratio?(widths) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 58
def matches_ratio?(widths)
  norm = normalized_ratio(widths)

  ONE.include?(norm[0]) &&
  ONE.include?(norm[1]) &&
  THREE.include?(norm[2]) &&
  ONE.include?(norm[3]) &&
  ONE.include?(norm[4])
end
new(*args) click to toggle source
Calls superclass method
# File lib/qrio/finder_pattern_slice.rb, line 19
def initialize(*args)
  @neighbors = []
  super
end
normalized_ratio(widths) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 68
def normalized_ratio(widths)
  scale = (widths[0] + widths[1] + widths[3] + widths[4]) / 4.0
  widths.map{|w| w / scale }
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 74
def <=>(other)
  return -1 if offset < other.offset
  return  1 if offset > other.offset
  origin <=> other.origin
end
adjacent?(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 88
def adjacent?(other)
  endpoints_match?(other) && offset_matches?(other)
end
aspect_ratio() click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 32
def aspect_ratio
  breadth / length.to_f
end
breadth_diff(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 128
def breadth_diff(other)
  (breadth - other.breadth).abs / breadth.to_f
end
breadth_matches?(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 132
def breadth_matches?(other)
  breadth_diff(other) <= WIDTH_TOLERANCE
end
class_name_prefix() click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 28
def class_name_prefix
  self.class.to_s.gsub(/^.*::/, '')[0,1]
end
endpoints_match?(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 92
def endpoints_match?(other)
  origin_matches?(other) && terminus_matches?(other)
end
intersects?(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 80
def intersects?(other)
  ! orientation_matches?(other) &&
  (other.origin..other.terminus).include?(offset) &&
  (origin..terminus).include?(other.offset) &&
  length_matches?(other) &&
  breadth_matches?(other)
end
length_diff(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 120
def length_diff(other)
  (length - other.length).abs / length.to_f
end
length_matches?(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 124
def length_matches?(other)
  length_diff(other) <= LENGTH_TOLERANCE
end
matches_aspect_ratio?() click to toggle source

based on the 1, 1, 3, 1, 1 width ratio, a finder pattern has total width of 7. an ideal grouped slice would then have aspect ratio of 3/7, since slice breadth would be 3 (just the center square) and length would be 7 (entire slice)

# File lib/qrio/finder_pattern_slice.rb, line 40
def matches_aspect_ratio?
  (0.25..0.59).include? aspect_ratio
end
normalized_offset_diff(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 112
def normalized_offset_diff(other)
  offset_diff(other) / length.to_f
end
offset_matches?(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 116
def offset_matches?(other)
  normalized_offset_diff(other) <= OFFSET_TOLERANCE
end
origin_diff(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 96
def origin_diff(other)
  (origin - other.origin).abs / length.to_f
end
origin_matches?(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 100
def origin_matches?(other)
  origin_diff(other) <= ENDPOINT_TOLERANCE
end
terminus_diff(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 104
def terminus_diff(other)
  (terminus - other.terminus).abs / length.to_f
end
terminus_matches?(other) click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 108
def terminus_matches?(other)
  terminus_diff(other) <= ENDPOINT_TOLERANCE
end
to_s() click to toggle source
# File lib/qrio/finder_pattern_slice.rb, line 24
def to_s
  "#{ class_name_prefix }[#{ to_coordinates.join(',') }]"
end