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.



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

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

Instance Method Details

#<=>(point) ⇒ Boolean



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



88
89
90
# File 'lib/geometry/edge.rb', line 88

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

#directionVector



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

def direction
    self.vector.normalize
end

#heightObject

Return the Geometry::Edge‘s length along the Y axis



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

def height
    (@first.y - @last.y).abs
end

#inspectObject Also known as: to_s



66
67
68
# File 'lib/geometry/edge.rb', line 66

def inspect
    'Edge(' + @first.inspect + ', ' + @last.inspect + ')'
end

#intersection(other) ⇒ Point



100
101
102
103
104
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
# File 'lib/geometry/edge.rb', line 100

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



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/geometry/edge.rb', line 72

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



46
47
48
# File 'lib/geometry/edge.rb', line 46

def reverse
    Edge.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_aObject



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

def to_a
    [@first, @last]
end

#vectorVector



132
133
134
# File 'lib/geometry/edge.rb', line 132

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

#widthObject

Return the Geometry::Edge‘s length along the X axis



62
63
64
# File 'lib/geometry/edge.rb', line 62

def width
    (@first.x - @last.x).abs
end