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