diff --git a/src/.properties b/src/.properties index ad0471d..6e0f77c 100644 --- a/src/.properties +++ b/src/.properties @@ -1,3 +1,4 @@ { - #format : #tonel -} \ No newline at end of file + #format : #tonel, + #version : #'1.0' +} diff --git a/src/Geometry-Tests/GSegmentTest.class.st b/src/Geometry-Tests/GSegmentTest.class.st index 3c3c134..75b7230 100644 --- a/src/Geometry-Tests/GSegmentTest.class.st +++ b/src/Geometry-Tests/GSegmentTest.class.st @@ -44,7 +44,10 @@ GSegmentTest >> testDistanceTo [ self assert: ((GSegment with: -2 , 4 with: 2 , 4) distanceTo: -2 , 4) equals: 0. self assert: ((GSegment with: -2 , 4 with: 2 , 4) distanceTo: 2 , 4) equals: 0. self assert: ((GSegment with: 477 / 11 , (149 / 2) with: -56.73661227723915 , 143.3189209406019) distanceTo: 36819 / 1022 , (82249 / 1022)) =~ 0.7697676365059569. - self assert: ((GSegment with: 838 / 41 , (4811 / 82) with: 57583 / 914 , (56095 / 914)) distanceTo: 57.998905906959145 , 61.11074842728413) =~ (2 * 0.02757564283371476) + self assert: ((GSegment with: 838 / 41 , (4811 / 82) with: 57583 / 914 , (56095 / 914)) distanceTo: 57.998905906959145 , 61.11074842728413) =~ (2 * 0.02757564283371476). + + self assert: ((GSegment with: -2 , 4 with: 2 , 4) distanceTo: 3 , 4) equals: 1. + self assert: ((GSegment with: -2 , 4 with: 2 , 4) distanceTo: -2 , 5) equals: 1. ] { #category : #tests } diff --git a/src/Geometry/GSegment.class.st b/src/Geometry/GSegment.class.st index 83707d8..f03c264 100644 --- a/src/Geometry/GSegment.class.st +++ b/src/Geometry/GSegment.class.st @@ -68,10 +68,31 @@ GSegment >> asGLine [ { #category : #properties } GSegment >> distanceTo: aGPoint [ - self flag: #todo. "«The distance between segments and rays may not be the same as the distance between their extended lines. » http://geomalgorithms.com/a07-_distance.html + + | vectSegment vectPoint t distance closestPoint| + + "See:https://paulbourke.net/geometry/pointlineplane/ + and: https://gist.github.com/mattdesl/47412d930dcd8cd765c871a65532ffac" + + distance := SmallInteger maxVal. + + "Vector from v1 to v2" + vectSegment := (v2 asPoint) - (v1 asPoint). + vectSegment isZero ifTrue:[ ^distance ]. + "Vector from v1 to P" + vectPoint := (aGPoint asPoint) - (v1 asPoint). + t := (vectSegment dotProduct: vectPoint) / (vectSegment dotProduct: vectSegment). + "Clamp t to [0, 1] to restrict to the segment" + t := (t max: 0) min: 1. + + "Closest point on segment to P" + closestPoint := (v1 asPoint) + (vectSegment * t). + distance := (aGPoint asPoint) distanceTo: closestPoint. + + ^distance + + - So apparently this implementation is wrong." - ^ self asGLine distanceTo: aGPoint ] { #category : #comparing }