Kilon
I can probably help you as it was in a Smalltalk application that I
developed in the early 1990s, ObjectiveFM, for my doctoral dissertation
and later was a commercial product. The method is below and it is for a
cubic Bezier spline. I am considering add a GIS package to Pharo and
would like to have assistance. I would also note that you should look at
the series of books called Graphics Gems (5 books) that are a great
resource.
Bob Williams
correlatesTo: testPoint within: correlationDistance
| dz index point return singleSpline aPoint testReturn |
"self halt."
aPoint := testPoint.
return := nil.
dz := self controlPoints first - aPoint.
((dz dotProduct: dz) < self minimumDistance)
ifTrue: [
^ self controlPoints first ].
dz := self controlPoints last - aPoint.
((dz dotProduct: dz) < self minimumDistance)
ifTrue: [
^ self controlPoints last].
index := -2.
((controlPoints size) // 3) timesRepeat: [
index := index + 3.
"eliminate segments from consideration if the bounding box about
them does not contain aPoint"
singleSpline := OFMSingleBezierSpline createFrom:
(Array with: (controlPoints at: index)
with: (controlPoints at: index +1)
with: (controlPoints at: index +2)
with: (controlPoints at: index +3)
point := singleSpline nearestPointOnCurveFor: aPoint.
(point notNil)
ifTrue: [
((point distanceFrom: aPoint) <= correlationDistance)
ifTrue: [ testReturn := true ]
ifFalse: [ testReturn := false ] ]
ifFalse: [
point := ((singleSpline z1 distanceFrom: aPoint) <
(singleSpline z2 distanceFrom: aPoint))
ifTrue: [ singleSpline z1 ] ifFalse: [singleSpline z2 ].
((point distanceFrom: aPoint) < correlationDistance)
ifTrue: [ testReturn := true ]
ifFalse: [ testReturn := false ] ].
(testReturn)
ifTrue: [
(return isNil)
ifTrue: [
return := point ]
ifFalse: [
((point distanceFrom: aPoint) < (return
distanceFrom: aPoint))
ifTrue: [return := point] ]]].
^return