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