Class: Geometry::Edge
- Inherits:
-
Object
- Object
- Geometry::Edge
- Defined in:
- lib/geometry/edge.rb
Overview
Instance Attribute Summary collapse
-
#direction ⇒ Vector
readonly
A unit Vector pointing from first to last.
-
#first ⇒ Object
readonly
Returns the value of attribute first.
-
#last ⇒ Object
readonly
Returns the value of attribute last.
-
#vector ⇒ Vector
readonly
A Vector pointing from first to last.
Instance Method Summary collapse
-
#<=>(point) ⇒ Boolean
Returns 1 if the Point is strictly to the left of the receiver, -1 to the right, and 0 if the point is on the receiver.
-
#==(other) ⇒ Object
Two Edges are equal if both have equal Points in the same order.
-
#connected?(other) ⇒ Bool
Returns true if the receiver and the passed Edge share an endpoint.
-
#height ⇒ Object
Return the Edge‘s length along the Y axis.
- #initialize(point0, point1) ⇒ Edge constructor
- #inspect ⇒ Object (also: #to_s)
-
#intersection(other) ⇒ Point
Find the intersection of two Edges (bloggingmath.wordpress.com/2009/05/29/line-segment-intersection/).
-
#length ⇒ Number
The length of the Edge.
-
#parallel?(edge) ⇒ Bool
Returns true if the passed Edge is parallel to the receiver.
-
#reverse ⇒ Object
Return a new Edge with swapped endpoints.
-
#reverse! ⇒ Object
In-place swap the endpoints.
- #to_a ⇒ Object
-
#width ⇒ Object
Return the Edge‘s length along the X axis.
Constructor Details
#initialize(point0, point1) ⇒ Edge
Construct a new Geometry::Edge object from any two things that can be converted to a Point.
20 21 22 |
# File 'lib/geometry/edge.rb', line 20 def initialize(point0, point1) @first, @last = [Point[point0], Point[point1]] end |
Instance Attribute Details
#direction ⇒ Vector (readonly)
Returns A unit Vector pointing from first to last.
100 101 102 |
# File 'lib/geometry/edge.rb', line 100 def direction @direction ||= self.vector.normalize end |
#first ⇒ Object (readonly)
Returns the value of attribute first.
16 17 18 |
# File 'lib/geometry/edge.rb', line 16 def first @first end |
#last ⇒ Object (readonly)
Returns the value of attribute last.
16 17 18 |
# File 'lib/geometry/edge.rb', line 16 def last @last end |
Instance Method Details
#<=>(point) ⇒ Boolean
Returns 1 if the Point is strictly to the left of the receiver, -1 to the right, and 0 if the point is on the receiver
31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/geometry/edge.rb', line 31 def <=>(point) case point when Point k = (@last.x - @first.x) * (point.y - @first.y) - (point.x - @first.x) * (@last.y - @first.y) if 0 == k (((@first.x <=> point.x) + (@last.x <=> point.x)).abs <= 1) && (((@first.y <=> point.y) + (@last.y <=> point.y)).abs <= 1) ? 0 : nil else k <=> 0 end else raise ArgumentError, "Can't spaceship with #{point.class}" end end |
#==(other) ⇒ Object
Two Edges are equal if both have equal Points in the same order
25 26 27 |
# File 'lib/geometry/edge.rb', line 25 def ==(other) (@first == other.first) && (@last == other.last) end |
#connected?(other) ⇒ Bool
Returns true if the receiver and the passed Geometry::Edge share an endpoint
94 95 96 |
# File 'lib/geometry/edge.rb', line 94 def connected?(other) (@first == other.last) || (@last == other.first) || (@first == other.first) || (@last == other.last) end |
#height ⇒ Object
Return the Geometry::Edge‘s length along the Y axis
62 63 64 |
# File 'lib/geometry/edge.rb', line 62 def height (@first.y - @last.y).abs end |
#inspect ⇒ Object Also known as: to_s
71 72 73 |
# File 'lib/geometry/edge.rb', line 71 def inspect 'Edge(' + @first.inspect + ', ' + @last.inspect + ')' end |
#intersection(other) ⇒ Point
Find the intersection of two Geometry::Edges (bloggingmath.wordpress.com/2009/05/29/line-segment-intersection/)
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/geometry/edge.rb', line 107 def intersection(other) return self.first if (self.first == other.first) or (self.first == other.last) return self.last if (self.last == other.first) or (self.last == other.last) p0, p1 = self.first, self.last p2, p3 = other.first, other.last v1, v2 = self.vector, other.vector denominator = v1[0] * v2[1] - v2[0] * v1[1] # v1 x v2 p = p0 - p2 if denominator == 0 # collinear, so check for overlap if 0 == (-v1[1] * p.x + v1[0] * p.y) # collinear? # The edges are collinear, but do they overlap? # Project them onto the x and y axes to find out left1, right1 = [self.first[0], self.last[0]].sort bottom1, top1 = [self.first[1], self.last[1]].sort left2, right2 = [other.first[0], other.last[0]].sort bottom2, top2 = [other.first[1], other.last[1]].sort !((left2 > right1) || (right2 < left1) || (top2 < bottom1) || (bottom2 > top1)) else nil end else s = (-v1[1] * p.x + v1[0] * p.y) / denominator # v1 x (p0 - p2) / denominator t = ( v2[0] * p.y - v2[1] * p.x) / denominator # v2 x (p0 - p2) / denominator p0 + v1 * t if ((0..1) === s) && ((0..1) === t) end end |
#length ⇒ Number
Returns the length of the Geometry::Edge.
57 58 59 |
# File 'lib/geometry/edge.rb', line 57 def length @length ||= vector.magnitude end |
#parallel?(edge) ⇒ Bool
Returns true if the passed Geometry::Edge is parallel to the receiver
77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/geometry/edge.rb', line 77 def parallel?(edge) v1 = self.direction v2 = edge.direction winding = v1[0]*v2[1] - v1[1]*v2[0] if 0 == winding # collinear? if v1 == v2 1 # same direction else -1 # opposite direction end else false end end |
#reverse ⇒ Object
Return a new Geometry::Edge with swapped endpoints
46 47 48 |
# File 'lib/geometry/edge.rb', line 46 def reverse self.class.new(@last, @first) end |
#reverse! ⇒ Object
In-place swap the endpoints
51 52 53 54 |
# File 'lib/geometry/edge.rb', line 51 def reverse! @first, @last = @last, @first self end |
#to_a ⇒ Object
144 145 146 |
# File 'lib/geometry/edge.rb', line 144 def to_a [@first, @last] end |
#width ⇒ Object
Return the Geometry::Edge‘s length along the X axis
67 68 69 |
# File 'lib/geometry/edge.rb', line 67 def width (@first.x - @last.x).abs end |