Class: Geospatial::Polygon
- Inherits:
-
Object
- Object
- Geospatial::Polygon
- Defined in:
- lib/geospatial/polygon.rb
Instance Attribute Summary collapse
-
#points ⇒ Object
readonly
Returns the value of attribute points.
Class Method Summary collapse
Instance Method Summary collapse
- #bounding_box ⇒ Object
- #edges ⇒ Object
- #freeze ⇒ Object
- #include?(other) ⇒ Boolean
- #include_point?(point) ⇒ Boolean
-
#initialize(points) ⇒ Polygon
constructor
A new instance of Polygon.
- #intersect?(other) ⇒ Boolean
- #intersect_with_box?(other) ⇒ Boolean
- #to_s ⇒ Object
-
#winding_number(p) ⇒ Number
Test a 2D point for inclusion in the polygon.
Constructor Details
#initialize(points) ⇒ Polygon
Returns a new instance of Polygon.
29 30 31 32 |
# File 'lib/geospatial/polygon.rb', line 29 def initialize(points) @points = points @bounding_box = nil end |
Instance Attribute Details
#points ⇒ Object (readonly)
Returns the value of attribute points.
34 35 36 |
# File 'lib/geospatial/polygon.rb', line 34 def points @points end |
Class Method Details
.[](*points) ⇒ Object
25 26 27 |
# File 'lib/geospatial/polygon.rb', line 25 def self.[] *points self.new(points) end |
.is_left(p0, p1, p2) ⇒ Object
61 62 63 64 65 66 |
# File 'lib/geospatial/polygon.rb', line 61 def self.is_left(p0, p1, p2) a = p1 - p0 b = p2 - p0 return (a[0] * b[1]) - (b[0] * a[1]) end |
Instance Method Details
#bounding_box ⇒ Object
40 41 42 |
# File 'lib/geospatial/polygon.rb', line 40 def bounding_box @bounding_box ||= Box.enclosing_points(@points) end |
#edges ⇒ Object
51 52 53 54 55 56 57 58 59 |
# File 'lib/geospatial/polygon.rb', line 51 def edges return to_enum(:edges) unless block_given? previous = @points.last @points.each do |point| yield previous, point previous = point end end |
#freeze ⇒ Object
44 45 46 47 48 49 |
# File 'lib/geospatial/polygon.rb', line 44 def freeze @points.freeze bounding_box.freeze super end |
#include?(other) ⇒ Boolean
113 114 115 |
# File 'lib/geospatial/polygon.rb', line 113 def include?(other) other.corners.all?{|corner| self.include_point?(corner)} end |
#include_point?(point) ⇒ Boolean
90 91 92 93 94 |
# File 'lib/geospatial/polygon.rb', line 90 def include_point?(point) return false unless bounding_box.include_point?(point) self.winding_number(point) == 1 end |
#intersect?(other) ⇒ Boolean
104 105 106 107 108 109 110 111 |
# File 'lib/geospatial/polygon.rb', line 104 def intersect?(other) case other when Box intersect_with_box?(other) when Circle intersect_with_circle?(other) end end |
#intersect_with_box?(other) ⇒ Boolean
96 97 98 99 100 101 102 |
# File 'lib/geospatial/polygon.rb', line 96 def intersect_with_box?(other) return true if @points.any?{|point| other.include_point?(point)} return true if other.corners.any?{|corner| self.include_point?(corner)} return false end |
#to_s ⇒ Object
36 37 38 |
# File 'lib/geospatial/polygon.rb', line 36 def to_s "#{self.class}#{@points.inspect}" end |
#winding_number(p) ⇒ Number
Test a 2D point for inclusion in the polygon.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/geospatial/polygon.rb', line 71 def winding_number(p) count = 0 edges.each do |pa, pb| if pa[1] <= p[1] if pb[1] >= p[1] and Polygon.is_left(pa, pb, p) > 0 count += 1 end else if pb[1] <= p[1] and Polygon.is_left(pa, pb, p) < 0 count -= 1 end end end return count end |