Class: PerfectShape::Point

Inherits:
Shape
  • Object
show all
Includes:
PointLocation
Defined in:
lib/perfect_shape/point.rb

Overview

Point class includes point-specific operations like ‘#==`, `point_distance` and a fuzzy `contain?` matcher

Instance Attribute Summary

Attributes included from PointLocation

#x, #y

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PointLocation

#first_point, #min_x, #min_y

Methods inherited from Shape

#==, #bounding_box, #center_point, #center_x, #center_y, #height, #min_x, #min_y, #width

Constructor Details

#initialize(x_or_point = nil, y_arg = nil, x: nil, y: nil) ⇒ Point

Returns a new instance of Point.



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/perfect_shape/point.rb', line 56

def initialize(x_or_point = nil, y_arg = nil, x: nil, y: nil)
  if x_or_point.is_a?(Array)
    x, y = x_or_point
    super(x: x, y: y)
  elsif x_or_point && y_arg
    super(x: x_or_point, y: y_arg)
  else
    x ||= 0
    y ||= 0
    super(x: x, y: y)
  end
end

Class Method Details

.normalize_point(x_or_point, y = nil) ⇒ Object

Normalizes point args whether two-number Array or x, y args returning normalized point array of two BigDecimal’s

Parameters:

  • x_or_point

    The point or X coordinate of the point to test.

  • y (defaults to: nil)

    The Y coordinate of the point to test.

Returns:

  • Array of x and y BigDecimal’s representing point



44
45
46
47
48
49
50
# File 'lib/perfect_shape/point.rb', line 44

def normalize_point(x_or_point, y = nil)
  x = x_or_point
  x, y = x if y.nil? && x_or_point.is_a?(Array) && x_or_point.size == 2
  x = x.is_a?(BigDecimal) ? x : BigDecimal(x.to_s)
  y = y.is_a?(BigDecimal) ? y : BigDecimal(y.to_s)
  [x, y]
end

.point_distance(x, y, px, py) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/perfect_shape/point.rb', line 29

def point_distance(x, y, px, py)
  x = x.is_a?(BigDecimal) ? x : BigDecimal(x.to_s)
  y = y.is_a?(BigDecimal) ? y : BigDecimal(y.to_s)
  px = px.is_a?(BigDecimal) ? px : BigDecimal(px.to_s)
  py = py.is_a?(BigDecimal) ? py : BigDecimal(py.to_s)
  BigDecimal(Math.sqrt((px - x)**2 + (py - y)**2).to_s)
end

Instance Method Details

#contain?(x_or_point, y = nil, outline: true, distance_tolerance: 0) ⇒ Boolean

Checks if points match, with distance tolerance (0 by default)

false if the point is too far.

Parameters:

  • x

    The X coordinate of the point to test.

  • y (defaults to: nil)

    The Y coordinate of the point to test.

  • distance_tolerance (defaults to: 0)

    The distance from point to tolerate (0 by default)

Returns:

  • (Boolean)

    true if the point is close enough within distance tolerance,



85
86
87
88
89
90
# File 'lib/perfect_shape/point.rb', line 85

def contain?(x_or_point, y = nil, outline: true, distance_tolerance: 0)
  x, y = Point.normalize_point(x_or_point, y)
  return unless x && y
  distance_tolerance = BigDecimal(distance_tolerance.to_s)
  point_distance(x, y) <= distance_tolerance
end

#intersect?(rectangle) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/perfect_shape/point.rb', line 99

def intersect?(rectangle)
  rectangle.contain?(self.to_a)
end

#max_xObject



69
70
71
# File 'lib/perfect_shape/point.rb', line 69

def max_x
  x
end

#max_yObject



73
74
75
# File 'lib/perfect_shape/point.rb', line 73

def max_y
  y
end

#point_distance(x_or_point, y = nil) ⇒ Object



92
93
94
95
96
97
# File 'lib/perfect_shape/point.rb', line 92

def point_distance(x_or_point, y = nil)
  x, y = Point.normalize_point(x_or_point, y)
  return unless x && y
  
  Point.point_distance(self.x, self.y, x, y)
end

#to_aObject

Convert to pair Array of x,y coordinates



104
105
106
# File 'lib/perfect_shape/point.rb', line 104

def to_a
  [self.x, self.y]
end