Computing heading

David T. Lewis lewis at mail.msen.com
Sun Jan 4 17:34:35 UTC 2004


On Sun, Jan 04, 2004 at 12:41:19AM -0800, 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.
> 
> Any pointers or suggestions?
> 
> -Jack

Hi Jack, welcome to Squeak.

Bert gave you a good answer for the problem you are trying to solve, but as a
newcomer to Squeak you may also be interested in knowing "how do I write
this math formula in Squeak?". To answer that, I'm going to drop down a level
into the Smalltalk language that is working underneath the EToys envinroment.

If you were trying to write a C function to solve your problem, you would poke
through the manuals and translate your formula into a function that might look
more or less like this:

double get_tc1(double lat1, double lon1, double lat2, double lon2)
{
  return fmod(atan2(sin(lon1-lon2)*cos(lat2),
    cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon1-lon2)),
      2*M_PI);
}

In Squeak, you would toss out the manuals (well, there aren't any manuals to
toss out, but you don't need them anyway). Go the the "Tools" flap on the right
side of the screen, and pull out a Workspace and an Method Finder (which opens
up a "Selector Browser", don't ask me why). You can use the Selector Browser
to find the math functions you need, and you can build up your formula piece
by piece in the Workspace, testing it as you go.

In the upper left pane of the Selector Browser, try entering "cos" and seeing
what you come up with. You will see the arcCos method right away, and the
cos method a little further down the list. After you experiment a little with
this, you will see that the methods that you are looking for tend to live in
the classes called Number and Float, so you can open browsers on these classes
and find all of the normal arithmatic and math functions that you would expect.

A couple of things are a bit tricky though. In the C program, you needed to
use the fmod() function, which is specifically designed to work with double
precision floating point data types. If you wanted to use a modulo function
for integers, you would have to use the % operator instead of fmod(), and
if you were using other kinds of numbers, you might need to use the fmodf()
function or the fmodl() function. In Squeak Smalltalk, the numbers are all
smart enough to figure out how to interact with one another, so once you
look through the arithmatic operators and find "\\" representing the modulo
function, you can just use it on any kind of number (including Float, which
is a double precision floating point under the covers).

The other tricky thing is that instead of using the C macro M_PI to represent
the constant value for pi, you can look for "pi" in the Selector Browser, and
find out that there is a "class side method" that shows up as "Float class pi".
This is where Squeak remembers the constant value of pi, and you can refer to
it by evaluating the expression "Float pi".

One more small oddity: In this example, I will use ":=" as the assignment
operator.  When you are doing this in Squeak, you can use the underscore
character "_" for assignment instead of ":=". It will show up as a nice
left-arrow in Squeak, and it means exactly the same thing as ":=". You will
find that most of the code in Squeak uses the left arrow (underscore) instead
of ":=", but since it would look funny in this email message, I used ":="
for the example.

That's all you need to know to start building up your formula.  If you go to
your Workspace and enter some numbers and expressions to play around with,
you might end up with something like this:

---- evaluate the following in your workspace ----
lat1 _ 203.
lon1 _ 113.
lat2 _ 479.
lon2 _ 501.

tc1 := (((lon1 - lon2) sin * lat2 cos)
         arcTan: ((lat1 cos * lat2 sin) - (lat1 sin * lat2 cos * (lon1 - lon2) cos)))
           \\ (2 * Float pi)
---- end of workspace stuff ----

This produces the same result as the C program (through the first 13 significant
digits, which is all you get out of double precision anyway). The values that
assigned to lat1, lon1, lat2, and lon2 are just number that I made up, you can
experiment with any values you want.

Of course, you can turn the Smalltalk expression into a method that you can call
from other objects. This makes it equivalent to the function call in C.  And it
is also very interesting to try evaluating your expression in the debugger, which
you can do by adding the expression "self halt." in your workspace right before
the "tcl :=  ... " stuff. Now when you evaluate the code in your workspace, a
debugger will open. Experiment with this, and you will find that you can step
through the formula evaluation and see exactly how the various number objects
are interacting with one another and how the math functions work.

But at this point, you should probably go back to Bert's answer, which will head
you back in the direction you really wanted to go.

Hope this helps,

Dave




More information about the Squeak-dev mailing list