class GeometricSegment

Public Class Methods

new_by_arrays(point1_coordinates, point2_coordinates) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 6
def self.new_by_arrays(point1_coordinates, point2_coordinates)
  self.new(GeometricPoint.new_by_array(point1_coordinates),
           GeometricPoint.new_by_array(point2_coordinates))
end

Protected Class Methods

have_intersecting_bounds?(segment1, segment2) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 102
def self.have_intersecting_bounds?(segment1, segment2)
  intersects_on_x_axis =
    (segment1.leftmost_endpoint.x < segment2.rightmost_endpoint.x ||
    segment1.leftmost_endpoint.x == segment2.rightmost_endpoint.x) &&
    (segment2.leftmost_endpoint.x < segment1.rightmost_endpoint.x ||
    segment2.leftmost_endpoint.x == segment1.rightmost_endpoint.x)

  intersects_on_y_axis =
    (segment1.bottommost_endpoint.y < segment2.topmost_endpoint.y ||
    segment1.bottommost_endpoint.y == segment2.topmost_endpoint.y) &&
    (segment2.bottommost_endpoint.y < segment1.topmost_endpoint.y ||
    segment2.bottommost_endpoint.y == segment1.topmost_endpoint.y)

  intersects_on_x_axis && intersects_on_y_axis
end

Public Instance Methods

bottommost_endpoint() click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 11
def bottommost_endpoint
  ((point1.y <=> point2.y) == -1) ? point1 : point2
end
contains_point?(point) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 27
def contains_point?(point)
  GeometricDistance.new(point1, point2).distance ===
    GeometricDistance.new(point1, point).distance + GeometricDistance.new(point, point2).distance
end
distance_to(point) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 32
def distance_to(point)
  q = point.to_vector
  p1 = point1.to_vector
  p2 = point2.to_vector

  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 GeometricDistance.new(q, p).distance
end
intersection_point_with(segment) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 55
def intersection_point_with(segment)
  raise GeometricSegmentsDoNotIntersect unless intersects_with?(segment)
  raise GeometricSegmentsOverlap 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);

  t = numerator.to_f / denominator;

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

  GeometricPoint.new(x, y)
end
intersects_with?(segment) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 72
def intersects_with?(segment)
  GeometricSegment.have_intersecting_bounds?(self, segment) &&
    lies_on_line_intersecting?(segment) &&
    segment.lies_on_line_intersecting?(self)
end
leftmost_endpoint() click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 15
def leftmost_endpoint
  ((point1.x <=> point2.x) == -1) ? point1 : point2
end
length() click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 78
def length
  GeometricDistance.new(point1, point2).distance
end
lies_on_one_line_with?(segment) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 82
def lies_on_one_line_with?(segment)
  GeometricSegment.new(point1, segment.point1).parallel_to?(self) &&
    GeometricSegment.new(point1, segment.point2).parallel_to?(self)
end
overlaps?(segment) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 87
def overlaps?(segment)
  GeometricSegment.have_intersecting_bounds?(self, segment) &&
    lies_on_one_line_with?(segment)
end
parallel_to?(segment) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 92
def parallel_to?(segment)
  to_vector.collinear_with?(segment.to_vector)
end
rightmost_endpoint() click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 19
def rightmost_endpoint
  ((point1.x <=> point2.x) == 1) ? point1 : point2
end
to_vector() click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 96
def to_vector
  GeometricVector.new(point2.x - point1.x, point2.y - point1.y)
end
topmost_endpoint() click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 23
def topmost_endpoint
  ((point1.y <=> point2.y) == 1) ? point1 : point2
end

Protected Instance Methods

lies_on_line_intersecting?(segment) click to toggle source
# File lib/flash_math/modules/geometry/geometric_segment.rb, line 118
def lies_on_line_intersecting?(segment)
  vector_to_first_endpoint = GeometricSegment.new(self.point1, segment.point1).to_vector
  vector_to_second_endpoint = GeometricSegment.new(self.point1, segment.point2).to_vector

  #FIXME: '>=' and '<=' method of Fixnum and Float should be overriden too (take precision into account)
  # there is a rare case, when this method is wrong due to precision
  self.to_vector.cross_product(vector_to_first_endpoint) *
    self.to_vector.cross_product(vector_to_second_endpoint) <= 0
end