 Ned Konz ned at squeakland.org
Sun Jan 4 18:37:28 UTC 2004

```On Sunday 04 January 2004 12:41 am, Jack Johnson wrote:
> I was messing around with EToys and grabbed an arrow morph and a couple
> of ellipses and wanted to have the arrow morph automatically place
> itself between the two ellipses and point from one to the other.
>
> The placement was easy, but I had trouble computing the heading.  I did
> come across a formula used for computing a bearing based on two map
> coordinates:
>
> tc1=mod(atan2(sin(lon1-lon2)*cos(lat2),cos(lat1)*sin(lat2)-
> sin(lat1)*cos(lat2)*cos(lon1-lon2)),2*pi)
>
> which would work just fine, but being relatively new to Squeak I'm at a
> loss for how to implement it, or how to even find out if/how Squeak
> implements the atan2 function.

Well, the math has been described. However, there's another strategy, and
that's to use my Connectors package.

In Connectors, I had to do two things to do what you describe (say if you make
a Connector and tell both of its ends to "attach to nearest point to
center").

* in EllipseMorph, I added this method, which uses the ellipse formula to get
the point on the border that is along the line from the center to some other
point (in your case, the center of the other ellipse):

intersectionWithLineSegmentFromCenterTo: aPoint
| dx aSquared bSquared m mSquared xSquared x y dy |
(self containsPoint: aPoint)
ifTrue: [ ^aPoint ].
dx _ aPoint x - self center x.
dy _ aPoint y - self center y.
dx = 0
ifTrue: [ ^self bounds pointNearestTo: aPoint ].
m _ dy / dx.
mSquared _ m squared.
aSquared _ (self bounds width / 2) squared.
bSquared _ (self bounds height / 2) squared.
xSquared _ 1 / ((1 / aSquared) + (mSquared / bSquared)).
x _ xSquared sqrt.
dx < 0 ifTrue: [ x _ x negated ].
y _ m * x.
^ self center + (x @ y) asIntegerPoint.

* The Connectors themselves (well, actually their ends) use the Morphic
"stepping" behavior to constantly re-adjust themselves per their attachment
specification. (so for instance you could have one end attached as above, and
another end attached to something else). So each one of them would be
periodically computing the above (passing as an argument the location of the
other one), and moving the attached line vertex if necessary.

```