Class: Geometry::Edge

Inherits:
Object
  • Object
show all
Defined in:
lib/geometry/edge.rb

Overview

An edge. It’s a line segment between 2 points. Generally part of a Polygon.

Usage

edge = Geometry::Edge([1,1], [2,2])

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(point0, point1) ⇒ Edge

Construct a new Geometry::Edge object from any two things that can be converted to a Point.



25
26
27
# File 'lib/geometry/edge.rb', line 25

def initialize(point0, point1)
    @first, @last = [Point[point0], Point[point1]]
end

Instance Attribute Details

#firstObject (readonly)

Returns the value of attribute first.



16
17
18
# File 'lib/geometry/edge.rb', line 16

def first
  @first
end

#lastObject (readonly)

Returns the value of attribute last.



16
17
18
# File 'lib/geometry/edge.rb', line 16

def last
  @last
end

#optionsObject



18
19
20
21
# File 'lib/geometry/edge.rb', line 18

def options
  @options = {} if !@options
  @options
end

Instance Method Details

#<=>(point) ⇒ Boolean



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/geometry/edge.rb', line 36

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



30
31
32
# File 'lib/geometry/edge.rb', line 30

def ==(other)
    (@first == other.first) && (@last == other.last)
end

#connected?(other) ⇒ Bool



93
94
95
# File 'lib/geometry/edge.rb', line 93

def connected?(other)
    (@first == other.last) || (@last == other.first) || (@first == other.first) || (@last == other.last)
end

#directionVector



98
99
100
# File 'lib/geometry/edge.rb', line 98

def direction
    self.vector.normalize
end

#heightObject

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

#inspectObject 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



105
106
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
# File 'lib/geometry/edge.rb', line 105

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

#parallel?(edge) ⇒ Bool



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/geometry/edge.rb', line 77

def parallel?(edge)
    v1, v2 = self.direction, 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

#reverseObject

Return a new Geometry::Edge with swapped endpoints



51
52
53
# File 'lib/geometry/edge.rb', line 51

def reverse
    Edge.new(@last, @first)
end

#reverse!Object

In-place swap the endpoints



56
57
58
59
# File 'lib/geometry/edge.rb', line 56

def reverse!
    @first, @last = @last, @first
    self
end

#to_aObject



141
142
143
# File 'lib/geometry/edge.rb', line 141

def to_a
    [@first, @last]
end

#vectorVector



137
138
139
# File 'lib/geometry/edge.rb', line 137

def vector
    Vector[*((last-first).to_a)]
end

#widthObject

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