11module Geometry
22 class SegmentsDoNotIntersect < Exception ; end
33 class SegmentsOverlap < Exception ; end
4-
4+
55 class Segment < Struct . new ( :point1 , :point2 )
66 def self . new_by_arrays ( point1_coordinates , point2_coordinates )
7- self . new ( Point . new_by_array ( point1_coordinates ) ,
8- Point . new_by_array ( point2_coordinates ) )
7+ new ( Point . new_by_array ( point1_coordinates ) ,
8+ Point . new_by_array ( point2_coordinates ) )
99 end
1010
1111 def leftmost_endpoint
@@ -23,8 +23,8 @@ def topmost_endpoint
2323 def bottommost_endpoint
2424 ( ( point1 . y <=> point2 . y ) == -1 ) ? point1 : point2
2525 end
26-
27- def contains_point? ( point )
26+
27+ def contains_point? ( point )
2828 Geometry . distance ( point1 , point2 ) ===
2929 Geometry . distance ( point1 , point ) + Geometry . distance ( point , point2 )
3030 end
@@ -43,26 +43,32 @@ def intersects_with?(segment)
4343 lies_on_line_intersecting? ( segment ) &&
4444 segment . lies_on_line_intersecting? ( self )
4545 end
46-
46+
4747 def overlaps? ( segment )
4848 Segment . have_intersecting_bounds? ( self , segment ) &&
4949 lies_on_one_line_with? ( segment )
5050 end
51-
51+
5252 def intersection_point_with ( segment )
5353 raise SegmentsDoNotIntersect unless intersects_with? ( segment )
5454 raise SegmentsOverlap if overlaps? ( segment )
55-
55+
5656 numerator = ( segment . point1 . y - point1 . y ) * ( segment . point1 . x - segment . point2 . x ) -
5757 ( segment . point1 . y - segment . point2 . y ) * ( segment . point1 . x - point1 . x ) ;
58- denominator = ( point2 . y - point1 . y ) * ( segment . point1 . x - segment . point2 . x ) -
59- ( segment . point1 . y - segment . point2 . y ) * ( point2 . x - point1 . x ) ;
58+ denominator = ( point2 . y - point1 . y ) *
59+ ( segment . point1 . x - segment . point2 . x ) -
60+ ( segment . point1 . y - segment . point2 . y ) *
61+ ( point2 . x - point1 . x )
62+
63+ if numerator . is_a? ( Integer ) && denominator . is_a? ( Integer )
64+ numerator = numerator . to_f
65+ end
66+
67+ t = numerator / denominator
6068
61- t = numerator . to_f / denominator ;
62-
6369 x = point1 . x + t * ( point2 . x - point1 . x )
64- y = point1 . y + t * ( point2 . y - point1 . y )
65-
70+ y = point1 . y + t * ( point2 . y - point1 . y )
71+
6672 Point . new ( x , y )
6773 end
6874
@@ -91,13 +97,13 @@ def distance_to(point)
9197 return Geometry . distance ( q , p )
9298 end
9399
94- def length
100+ def length
95101 Geometry . distance ( point1 , point2 )
96102 end
97103
98104 def to_vector
99105 Vector . new ( point2 . x - point1 . x , point2 . y - point1 . y )
100- end
106+ end
101107
102108 protected
103109
@@ -107,7 +113,7 @@ def self.have_intersecting_bounds?(segment1, segment2)
107113 segment1 . leftmost_endpoint . x == segment2 . rightmost_endpoint . x ) &&
108114 ( segment2 . leftmost_endpoint . x < segment1 . rightmost_endpoint . x ||
109115 segment2 . leftmost_endpoint . x == segment1 . rightmost_endpoint . x )
110-
116+
111117 intersects_on_y_axis =
112118 ( segment1 . bottommost_endpoint . y < segment2 . topmost_endpoint . y ||
113119 segment1 . bottommost_endpoint . y == segment2 . topmost_endpoint . y ) &&
0 commit comments