[comp.lang.smalltalk] Bug Fix for Nearest-Point-On-Line

kww@cs.glasgow.ac.uk (Dr Kevin Waite) (05/07/90)

The ParcPlace Objectworks for Smalltalk 2.5 has a bug (feature?) in the
Point method #nearestIntegerPointOnLineFrom:to: (and also the floating
point version, but I have not checked that out).  The problem arises
when the perpendicular from the receiver Point does not touch the 
given line segment.  For example, the expression 

	0@0 nearestIntegerPointOnLineFrom: 10@10 to: 100@100

returns 0@0 and not 10@10 as one would expect.  The following file-in
rectifies this.   I'm sorry about the indentation but I didn't want
my mailer to baulk at extra-long lines.

I hope this is of use.
Cheers,
   Kevin

-----------------------  CUT HERE   ----------------------


'From Objectworks for Smalltalk-80(tm), Version 2.5 of 29 July 1989 on 7 May 1990 at 4:11:06 pm'!



!Point methodsFor: 'point functions'!

nearestIntegerPointOnLineFrom: point1 to: point2 
	"Answer the closest integer point to the receiver on the line 
	determined by (point1, point2)--much faster than the more 
	accurate version if the receiver and arguments are integer points"
	"120@40 nearestIntegerPointOnLineFrom: 30@120 to: 100@120"
 
	| dX dY newX newY dX2 dY2 intersect scale coeff |

	dX := point2 x - point1 x.
	dY := point2 y - point1 y.
	intersect := dX = 0
		ifTrue: [dY = 0
			ifTrue: [point1]
			ifFalse: [newX := point1 x.
				scale := (y - point1 y) / dY.
				newY := scale > 1 ifTrue: [point2 y] ifFalse: [
				 scale < 0 ifTrue: [point1 y] ifFalse: [y]].

				^(newX @ newY) rounded]
				]

		ifFalse: [dY = 0
			ifTrue: [x @ point1 y]
			ifFalse: 
				[dX2 := dX * dX.
				dY2 := dY * dY.
				coeff := ((dX * (y - point1 y)) - 
                                         ((x - point1 x) * dY)) / (dX2 + dY2).
				newX := x + (dY * coeff).
				newY := y - (dX * coeff).
				newX @ newY]].

	scale := (intersect x - point1 x) / dX.
 
	^(scale > 1 ifTrue: [point2] ifFalse: [
	 scale < 0 ifTrue: [point1] ifFalse: [intersect]]) rounded! !


---------------------------   CUT   HERE  -------------------------
-- 
Email:   kww@uk.ac.glasgow.cs  (JANET)
	 kww%cs.glasgow.ac.uk@nsfnet-relay.ac.uk  (INTERNET)
Address: Dept. of Computing Science,  University of Glasgow,
	 17 Lilybank Gardens,  Glasgow,  United Kingdom.  G12 8QQ