Class: Geometry::Segment

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#point1Object

Returns the value of attribute point1

Returns:

  • (Object)

    the current value of point1


5
6
7
# File 'lib/geometry/segment.rb', line 5

def point1
  @point1
end

#point2Object

Returns the value of attribute point2

Returns:

  • (Object)

    the current value of point2


5
6
7
# File 'lib/geometry/segment.rb', line 5

def point2
  @point2
end

Class Method Details

.new_by_arrays(point1_coordinates, point2_coordinates) ⇒ Object


6
7
8
9
# File 'lib/geometry/segment.rb', line 6

def self.new_by_arrays(point1_coordinates, point2_coordinates)
  new(Point.new_by_array(point1_coordinates),
      Point.new_by_array(point2_coordinates))
end

Instance Method Details

#bottommost_endpointObject


23
24
25
# File 'lib/geometry/segment.rb', line 23

def bottommost_endpoint
  ((point1.y <=> point2.y) == -1) ? point1 : point2
end

#contains_point?(point) ⇒ Boolean

Returns:

  • (Boolean)

27
28
29
30
# File 'lib/geometry/segment.rb', line 27

def contains_point?(point)
  Geometry.distance(point1, point2) ===
    Geometry.distance(point1, point) + Geometry.distance(point, point2)
end

#distance_to(point) ⇒ Object


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/geometry/segment.rb', line 75

def distance_to(point)
  q = point.to_vector
  p1 = point1.to_vector
  p2 = point2.to_vector

  return Geometry.distance(q, p1) if p1 == p2

  u = p2 - p1
  v = q - p1

  a = u.scalar_product(v)
  if a < 0
    p = p1
  else
    b = u.scalar_product(u)
    if a > b
      p = p2
    else
      p = p1 + (a.to_f / b * u)
    end
  end

  return Geometry.distance(q, p)
end

#intersection_point_with(segment) ⇒ Object


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/geometry/segment.rb', line 52

def intersection_point_with(segment)
  raise SegmentsDoNotIntersect unless intersects_with?(segment)
  raise SegmentsOverlap if overlaps?(segment)

  numerator = (segment.point1.y - point1.y) * (segment.point1.x - segment.point2.x) -
    (segment.point1.y - segment.point2.y) * (segment.point1.x - point1.x);
  denominator = (point2.y - point1.y) *
                (segment.point1.x - segment.point2.x) -
                (segment.point1.y - segment.point2.y) *
                (point2.x - point1.x)

  if numerator.is_a?(Integer) && denominator.is_a?(Integer)
    numerator = numerator.to_f
  end

  t = numerator / denominator

  x = point1.x + t * (point2.x - point1.x)
  y = point1.y + t * (point2.y - point1.y)

  Point.new(x, y)
end

#intersects_with?(segment) ⇒ Boolean

Returns:

  • (Boolean)

41
42
43
44
45
# File 'lib/geometry/segment.rb', line 41

def intersects_with?(segment)
  Segment.have_intersecting_bounds?(self, segment) &&
    lies_on_line_intersecting?(segment) &&
    segment.lies_on_line_intersecting?(self)
end

#leftmost_endpointObject


11
12
13
# File 'lib/geometry/segment.rb', line 11

def leftmost_endpoint
  ((point1.x <=> point2.x) == -1) ? point1 : point2
end

#lengthObject


100
101
102
# File 'lib/geometry/segment.rb', line 100

def length
  Geometry.distance(point1, point2)
end

#lies_on_one_line_with?(segment) ⇒ Boolean

Returns:

  • (Boolean)

36
37
38
39
# File 'lib/geometry/segment.rb', line 36

def lies_on_one_line_with?(segment)
  Segment.new(point1, segment.point1).parallel_to?(self) &&
    Segment.new(point1, segment.point2).parallel_to?(self)
end

#overlaps?(segment) ⇒ Boolean

Returns:

  • (Boolean)

47
48
49
50
# File 'lib/geometry/segment.rb', line 47

def overlaps?(segment)
  Segment.have_intersecting_bounds?(self, segment) &&
    lies_on_one_line_with?(segment)
end

#parallel_to?(segment) ⇒ Boolean

Returns:

  • (Boolean)

32
33
34
# File 'lib/geometry/segment.rb', line 32

def parallel_to?(segment)
  to_vector.collinear_with?(segment.to_vector)
end

#rightmost_endpointObject


15
16
17
# File 'lib/geometry/segment.rb', line 15

def rightmost_endpoint
  ((point1.x <=> point2.x) == 1) ? point1 : point2
end

#to_vectorObject


104
105
106
# File 'lib/geometry/segment.rb', line 104

def to_vector
  Vector.new(point2.x - point1.x, point2.y - point1.y)
end

#topmost_endpointObject


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

def topmost_endpoint
  ((point1.y <=> point2.y) == 1) ? point1 : point2
end