From 90caa8c70ba61fd4b42efb50022bff98d0cf0235 Mon Sep 17 00:00:00 2001 From: David Kaczowka Date: Thu, 11 Aug 2016 12:19:16 -0500 Subject: [PATCH 1/4] Allow intersection_point_with to work with BigDecimal. The method should only convert the numerator to a float if both numerator and denominator are integers. --- lib/geometry/segment.rb | 34 +++++++++++--------- test/segment/intersection_point_with_test.rb | 13 ++++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/geometry/segment.rb b/lib/geometry/segment.rb index b593d86..2f7f004 100644 --- a/lib/geometry/segment.rb +++ b/lib/geometry/segment.rb @@ -1,10 +1,10 @@ module Geometry class SegmentsDoNotIntersect < Exception; end class SegmentsOverlap < Exception; end - + class Segment < Struct.new(:point1, :point2) def self.new_by_arrays(point1_coordinates, point2_coordinates) - self.new(Point.new_by_array(point1_coordinates), + self.new(Point.new_by_array(point1_coordinates), Point.new_by_array(point2_coordinates)) end @@ -23,8 +23,8 @@ def topmost_endpoint def bottommost_endpoint ((point1.y <=> point2.y) == -1) ? point1 : point2 end - - def contains_point?(point) + + def contains_point?(point) Geometry.distance(point1, point2) === Geometry.distance(point1, point) + Geometry.distance(point, point2) end @@ -43,26 +43,30 @@ def intersects_with?(segment) lies_on_line_intersecting?(segment) && segment.lies_on_line_intersecting?(self) end - + def overlaps?(segment) Segment.have_intersecting_bounds?(self, segment) && lies_on_one_line_with?(segment) end - + 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) - + 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; - + 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) - + y = point1.y + t * (point2.y - point1.y) + Point.new(x, y) end @@ -91,13 +95,13 @@ def distance_to(point) return Geometry.distance(q, p) end - def length + def length Geometry.distance(point1, point2) end def to_vector Vector.new(point2.x - point1.x, point2.y - point1.y) - end + end protected @@ -107,7 +111,7 @@ def self.have_intersecting_bounds?(segment1, segment2) 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) && diff --git a/test/segment/intersection_point_with_test.rb b/test/segment/intersection_point_with_test.rb index 6c62864..2cd0756 100644 --- a/test/segment/intersection_point_with_test.rb +++ b/test/segment/intersection_point_with_test.rb @@ -1,5 +1,6 @@ require 'minitest/autorun' require 'geometry' +require 'bigdecimal' class IntersectionPointWithTest < Minitest::Test include Geometry @@ -18,6 +19,18 @@ def test_segments_intersect_at_the_endpoint assert_equal Point.new(2, 2), segment1.intersection_point_with(segment2) end + def test_big_decimal_segments_intersect_at_the_endpoint + segment1 = Segment.new_by_arrays([BigDecimal.new('-109.775390625'), BigDecimal.new('42.734102391081')], + [BigDecimal.new('-91.23046875'), BigDecimal.new('42.734102391081')]) + + segment2 = Segment.new_by_arrays([BigDecimal.new('-91.23046875'), BigDecimal.new('42.734102391081')], + [BigDecimal.new('-91.23046875'), BigDecimal.new('34.147272023649')]) + + + assert_equal Point.new(BigDecimal.new('-91.23046875'), BigDecimal.new('42.734102391081')), + segment1.intersection_point_with(segment2) + end + def test_segments_do_not_intersect segment1 = Segment.new_by_arrays([0, 0], [0, 2]) segment2 = Segment.new_by_arrays([1, 1], [2, 1]) From b33c399b6a1434b7698326736a72f682de82a635 Mon Sep 17 00:00:00 2001 From: David Kaczowka Date: Thu, 11 Aug 2016 12:34:01 -0500 Subject: [PATCH 2/4] Address emails from hound --- lib/geometry/segment.rb | 9 ++++---- test/segment/intersection_point_with_test.rb | 22 ++++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/geometry/segment.rb b/lib/geometry/segment.rb index 2f7f004..fb14de2 100644 --- a/lib/geometry/segment.rb +++ b/lib/geometry/segment.rb @@ -4,8 +4,8 @@ class SegmentsOverlap < Exception; end class Segment < Struct.new(:point1, :point2) def self.new_by_arrays(point1_coordinates, point2_coordinates) - self.new(Point.new_by_array(point1_coordinates), - Point.new_by_array(point2_coordinates)) + new(Point.new_by_array(point1_coordinates), + Point.new_by_array(point2_coordinates)) end def leftmost_endpoint @@ -55,14 +55,15 @@ def intersection_point_with(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) - + 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; + t = numerator / denominator x = point1.x + t * (point2.x - point1.x) y = point1.y + t * (point2.y - point1.y) diff --git a/test/segment/intersection_point_with_test.rb b/test/segment/intersection_point_with_test.rb index 2cd0756..cb8d9bb 100644 --- a/test/segment/intersection_point_with_test.rb +++ b/test/segment/intersection_point_with_test.rb @@ -1,6 +1,6 @@ require 'minitest/autorun' require 'geometry' -require 'bigdecimal' +require "bigdecimal" class IntersectionPointWithTest < Minitest::Test include Geometry @@ -20,14 +20,18 @@ def test_segments_intersect_at_the_endpoint end def test_big_decimal_segments_intersect_at_the_endpoint - segment1 = Segment.new_by_arrays([BigDecimal.new('-109.775390625'), BigDecimal.new('42.734102391081')], - [BigDecimal.new('-91.23046875'), BigDecimal.new('42.734102391081')]) - - segment2 = Segment.new_by_arrays([BigDecimal.new('-91.23046875'), BigDecimal.new('42.734102391081')], - [BigDecimal.new('-91.23046875'), BigDecimal.new('34.147272023649')]) - - - assert_equal Point.new(BigDecimal.new('-91.23046875'), BigDecimal.new('42.734102391081')), + segment1 = Segment.new_by_arrays([BigDecimal.new("-109.775390625"), + BigDecimal.new("42.734102391081")], + [BigDecimal.new("-91.23046875"), + BigDecimal.new("42.734102391081")]) + + segment2 = Segment.new_by_arrays([BigDecimal.new("-91.23046875"), + BigDecimal.new("42.734102391081")], + [BigDecimal.new("-91.23046875"), + BigDecimal.new("34.147272023649")]) + + assert_equal Point.new(BigDecimal.new("-91.23046875"), + BigDecimal.new("42.734102391081")), segment1.intersection_point_with(segment2) end From 831e13975b058b6da1570fc9658d147bcb930f70 Mon Sep 17 00:00:00 2001 From: David Kaczowka Date: Thu, 11 Aug 2016 12:36:18 -0500 Subject: [PATCH 3/4] Per hound: Align the operands of an expression in an assignment spanning multiple lines. --- lib/geometry/segment.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/geometry/segment.rb b/lib/geometry/segment.rb index fb14de2..eb7e2ea 100644 --- a/lib/geometry/segment.rb +++ b/lib/geometry/segment.rb @@ -56,8 +56,9 @@ def intersection_point_with(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); + (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 From 10f11539e5543de6b130ca53a867bb3e61d25b3b Mon Sep 17 00:00:00 2001 From: David Kaczowka Date: Thu, 11 Aug 2016 12:37:05 -0500 Subject: [PATCH 4/4] The semicolon should not be there. --- lib/geometry/segment.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/geometry/segment.rb b/lib/geometry/segment.rb index eb7e2ea..2157392 100644 --- a/lib/geometry/segment.rb +++ b/lib/geometry/segment.rb @@ -58,7 +58,7 @@ def intersection_point_with(segment) denominator = (point2.y - point1.y) * (segment.point1.x - segment.point2.x) - (segment.point1.y - segment.point2.y) * - (point2.x - point1.x); + (point2.x - point1.x) if numerator.is_a?(Integer) && denominator.is_a?(Integer) numerator = numerator.to_f