class Euclidean::Edge

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

Usage

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

Attributes

first[R]
last[R]

Public Class Methods

new(point0, point1) click to toggle source

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

# File lib/euclidean/edge.rb, line 17
def initialize(point0, point1)
  @first, @last = [Point[point0], Point[point1]]
end

Public Instance Methods

<=>(point) click to toggle source

@param [Point] point A {Point} to spaceship with @return [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

# File lib/euclidean/edge.rb, line 28
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) click to toggle source

Two Edges are equal if both have equal {Point}s in the same order

# File lib/euclidean/edge.rb, line 22
def ==(other)
  (@first == other.first) && (@last == other.last)
end
connected?(other) click to toggle source

@param [Edge] other The other {Edge} to check @return [Bool] Returns true if the receiver and the passed {Edge} share an endpoint

# File lib/euclidean/edge.rb, line 44
def connected?(other)
  (@first == other.last) || (@last == other.first) || (@first == other.first) || (@last == other.last)
end
direction() click to toggle source

@return [Vector] A unit {Vector} pointing from first to last

# File lib/euclidean/edge.rb, line 49
def direction
  self.vector.normalize
end
height() click to toggle source

Return the {Edge}‘s length along the Y axis

# File lib/euclidean/edge.rb, line 54
def height
  (@first.y - @last.y).abs
end
inspect() click to toggle source
# File lib/euclidean/edge.rb, line 58
def inspect
  'Edge(' + @first.inspect + ', ' + @last.inspect + ')'
end
Also aliased as: to_s
intersection(other) click to toggle source

Find the intersection of two {Edge}s (bloggingmath.wordpress.com/2009/05/29/line-segment-intersection/) @param [Edge] other The other {Edge} @return [Point] The intersection of the two {Edge}s, nil if they don’t intersect, true if they’re collinear and overlapping, and false if they’re collinear and non-overlapping

# File lib/euclidean/edge.rb, line 66
  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) click to toggle source

@return [Bool] Returns true if the passed {Edge} is parallel to the receiver

# File lib/euclidean/edge.rb, line 99
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
      true # 1  # same direction
    else
      true # -1 # opposite direction
    end
  else
    false
  end
end
reverse() click to toggle source

Return a new {Edge} with swapped endpoints

# File lib/euclidean/edge.rb, line 114
def reverse
  Edge.new(@last, @first)
end
reverse!() click to toggle source

In-place swap the endpoints

# File lib/euclidean/edge.rb, line 119
def reverse!
  @first, @last = @last, @first
  self
end
to_a() click to toggle source
# File lib/euclidean/edge.rb, line 124
def to_a
  [@first, @last]
end
to_s()
Alias for: inspect
vector() click to toggle source

@return [Vector] A {Vector} pointing from first to last

# File lib/euclidean/edge.rb, line 129
def vector
  Vector[*((last-first).to_a)]
end
width() click to toggle source

Return the {Edge}‘s length along the X axis

# File lib/euclidean/edge.rb, line 134
def width
  (@first.x - @last.x).abs
end