Class: EasyGeometry::D2::Ray

Inherits:
LinearEntity show all
Defined in:
lib/easy_geometry/d2/ray.rb

Overview

A Ray is a semi-line in the space with a source point and a direction.

Instance Attribute Summary

Attributes inherited from LinearEntity

#p1, #p2

Instance Method Summary collapse

Methods inherited from LinearEntity

#angle_between, #direction, #initialize, #intersection, #parallel_line, #parallel_to?, #perpendicular_line, #perpendicular_segment, #perpendicular_to?, #projection_point, #similar_to?, #slope, #span_test

Constructor Details

This class inherits a constructor from EasyGeometry::D2::LinearEntity

Instance Method Details

#==(other) ⇒ Object

Returns True if self and other are the same mathematical entities

Parameters:

GeometryEntity


64
65
66
67
# File 'lib/easy_geometry/d2/ray.rb', line 64

def ==(other)
  return false unless other.is_a?(Ray)
  self.source == other.source && self.contains?(other.p2)
end

#contains?(other) ⇒ Boolean

Is other GeometryEntity contained in this Ray?

Parameters:

GeometryEntity or Array of Numeric(coordinates)

Returns:

true if `other` is on this Ray.
false otherwise.


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/easy_geometry/d2/ray.rb', line 15

def contains?(other)
  other = Point.new(other[0], other[1]) if other.is_a?(Array)

  if other.is_a?(Point)
    if Point.is_collinear?(other, self.p1, self.p2)
      # if we're in the direction of the ray, our
      # direction vector dot the ray's direction vector
      # should be non-negative
      return (self.p2 - self.p1).dot(other - self.p1) >= 0
    end
  end

  if other.is_a?(Ray)
    if Point.is_collinear?(self.p1, self.p2, other.p1, other.p2)
      return (self.p2 - self.p1).dot(other.p2 - other.p1) > 0
    end
  end

  if other.is_a?(Segment)
    return true if self.contains?(other.p1) && self.contains?(other.p2)
  end

  return false
end

#distance(other) ⇒ Object

Finds the shortest distance between the ray and a point.

Parameters:

Point or Array of Numeric(coordinates)

Raises:

  • (TypeError)


45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/easy_geometry/d2/ray.rb', line 45

def distance(other)
  other = Point.new(other[0], other[1]) if other.is_a?(Array)
  raise TypeError, "Distance between Ray and #{ other.class } is not defined" unless other.is_a?(Point)

  return 0 if self.contains?(other)

  proj = Line.new(self.p1, self.p2).projection_point(other)
  if self.contains?(proj)
    return (other - proj).abs
  end
    
  (other - self.source).abs
end

#sourceObject

The point from which the ray emanates.



70
71
72
# File 'lib/easy_geometry/d2/ray.rb', line 70

def source
  self.p1
end

#xdirectionObject

The x direction of the ray.

Returns:

Positive infinity if the ray points in the positive x direction,
negative infinity if the ray points in the negative x direction,
or 0 if the ray is vertical.


81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/easy_geometry/d2/ray.rb', line 81

def xdirection
  return @xdirection if defined?(@xdirection)

  if self.p1.x < self.p2.x
    @xdirection = BigDecimal('Infinity')
  elsif self.p1.x == self.p2.x
    @xdirection = 0
  else
    @xdirection = -BigDecimal('Infinity')
  end

  @xdirection
end

#ydirectionObject

The y direction of the ray.

Returns:

Positive infinity if the ray points in the positive y direction,
negative infinity if the ray points in the negative y direction,
or 0 if the ray is horizontal.


102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/easy_geometry/d2/ray.rb', line 102

def ydirection
  return @ydirection if defined?(@ydirection)

  if self.p1.y < self.p2.y
    @ydirection = BigDecimal('Infinity')
  elsif self.p1.y == self.p2.y
    @ydirection = 0
  else
    @ydirection = -BigDecimal('Infinity')
  end

  @ydirection
end