Point.st
changeset 276 3b6d97620494
parent 217 a0400fdbc933
child 293 31df3850e98c
--- a/Point.st	Tue Feb 21 02:07:07 1995 +0100
+++ b/Point.st	Wed Feb 22 02:14:51 1995 +0100
@@ -21,7 +21,7 @@
 COPYRIGHT (c) 1989 by Claus Gittinger
 	      All Rights Reserved
 
-$Header: /cvs/stx/stx/libbasic/Point.st,v 1.15 1995-02-02 12:25:30 claus Exp $
+$Header: /cvs/stx/stx/libbasic/Point.st,v 1.16 1995-02-22 01:14:11 claus Exp $
 '!
 
 !Point class methodsFor:'documentation'!
@@ -42,7 +42,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libbasic/Point.st,v 1.15 1995-02-02 12:25:30 claus Exp $
+$Header: /cvs/stx/stx/libbasic/Point.st,v 1.16 1995-02-22 01:14:11 claus Exp $
 "
 !
 
@@ -631,6 +631,59 @@
     "
 
     ^ 0@0 quadrantContaining:self
+!
+
+nearestIntegerPointOnLineFrom: point1 to: point2 
+    "return 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.
+     This method was found in the Manchester goody library."
+
+    | dX dY newX newY dX2 dY2 intersect scale coeff |
+
+    dX := point2 x - point1 x.
+    dY := point2 y - point1 y.
+    (dX = 0)ifTrue: [
+	(dY = 0) ifTrue: [
+	    intersect := 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: [
+	    intersect := 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).
+	    intersect := newX @ newY
+	]
+    ].
+
+    scale := (intersect x - point1 x) / dX.
+
+    ^ (scale > 1 ifTrue: [point2] ifFalse: [
+      scale < 0 ifTrue: [point1] ifFalse: [intersect]]) rounded
+
+    "
+     120@40 nearestIntegerPointOnLineFrom: 30@120 to: 100@120 
+     0@0 nearestIntegerPointOnLineFrom: 10@10 to: 100@100 
+    "
 ! !
 
 !Point methodsFor:'printing & storing'!