arctan2 algorithm?

S

Simon Brooke

Patricia said:
If your current problem is mainly local walking, you can do a temporary
flat-Earth approximation to use until you get your atan2 working.

Do spherical geometry, in a full Java environment, to get the surface
distance corresponding to a degree of latitude and longitude in your
area. If you approximate to a sphere, the latitude distance is a
constant, and only longitude depends on location.

Pick an arbitrary local origin, and calculate flat Earth cartesian
coordinates relative to it by multiplying the differences longitude and
latitude by the conversion factors.

I agree that's a pragmatic approach, but I dislike special-case solutions.
The thing ought to work anywhere. I'll get there; enough kind people have
given me enough good approaches to work on.

--
(e-mail address removed) (Simon Brooke) http://www.jasmine.org.uk/~simon/
.::;===r==\
/ /___||___\____
//==\- ||- | /__\( MS Windows IS an operating environment.
//____\__||___|_// \|: C++ IS an object oriented programming language.
\__/ ~~~~~~~~~ \__/ Citroen 2cv6 IS a four door family saloon.
 
S

Simon Brooke

Patricia said:
I would test the atan2 implementation in a full Java environment,
comparing it to Math.atan2 which is far more accurate than you need.
Accept any answer that differs by no more than a couple of millionths of
a radian from the Math.atan2 answer.

Thanks, that sounds like an excellent suggestion.
 
J

Jeff

Jeff said:
ducnbyu said:
ducnbyu said:
Simon Brooke wrote:
I'm doing stuff on JavaME for which needs to do distance between arbitrary
geographic locations, so I need Math.atan2( double, double), which of
course isn't in JavaME.

Bother.

I've looked at Math.atan2 in src.zip, but it's doing a lot of horribly low
level stuff that I don't really understand. Can anyone point me to a
reasonably high-level algorithm for arctangent, in some reasonably high
level language or pseudo-language (doesn't have to be Java)?

--
(e-mail address removed) (Simon Brooke) http://www.jasmine.org.uk/~simon/
Iraq war: it's time for regime change...
... go now, Tony, while you can still go with dignity.
[update three years after this .sig was written: it's still relevant]

This shows how it's done in hardware using formulas easy to reproduce
in java.

http://www.electronics.dit.ie/staff/aschwarzbacher/research/ecs99.pdf

The key is to store precomputed values of atan(1/(2^n)) (n starts at 0)
and binary search for the desired accuracy. I tested this in Excel and
it converges to 8 decimal places in about 30 iterations. There's some
low hanging fruit for optimization. I didn't find the explanation for
choosing "d" completely clear, but it's just saying if y > 0 then d is
1 if y < 0 then d is -1 and if y = 0 then d is zero because you hit on
an exact answer (based on the accuracy of your precomputed table) and
you don't want further computations to change the result. In other
words you'd just want to stop iterating. If y never gets to zero then
you stop iterating when you run out of precomputed values.

BTW the above is for atan. You will need to query your values of x and
y to produce the correct result in -180 to 180 and -90 to 90 degree
spaces for geo coordinates for a true atan2 result.

I apologize for not knowing how to post code properly (sscce???), but I
put this together from a project from another language for PDAs. It is
pretty accurate, does not require anything more than +-*/. I tested
it and in a reasonable range (10-80 degrees tested) it was accurate to
3-4 places precision. It is quick-and-dirty, can be adjusted (iteration
count in the square root function, for example, can be adjusted up or
down).

/**
*
* @author Jeffrey Summers
*/
public class MiniMath {

/** Creates a new instance of MiniMath */
public MiniMath() {
}

public double mm_sqrt(double src) {
//method to calc sqrt using successive approximations
double hi, lo, midl;
midl = 0.0;
if (src > 1) {
lo = 1;
hi = src;
} else {
lo = src;
hi = 1;
}
for (int i = 1; i < 100; i++) {
midl = (hi + lo)/2.0;
if (midl*midl > src) {
hi = midl;
} else {
lo = midl;
}

}
return midl;
}
public double mm_asn(double src) {
// Calculate arcsin from degrees
return
(1.570796327-mm_sqrt(1-src)*(1.5707288-0.2121144*src+0.074261*src*src-0.0187293*src*src*src))/0.01745329252;
}
public double mm_atn(double src) {
// Calculate arctan from degrees
return (mm_asn(src/mm_sqrt(src*src+1)));
}
}

Meant to say 3-4 decimal places were accurate, with 2 digits before
(5-6 digits precision, again in my tests).
 
T

Thomas Fritsch

Thomas Fritsch said:
arctan2(y,x) = + arctan(y/x)
or - arctan(y/x) (depending on the signs of x and y)
Sorry for my error. It should be:
arctan2(y,x) = arctan(y/x) // if (x > 0)
or arctan(y/x) + pi // if (x said:
I did a quick google with: arctan +taylor

The Taylor series of arctan(x) (see
<http://en.wikipedia.org/wiki/Taylor_series> ) seems quite easy to
implement. But unfortunately it converges well only for small x
(i.e. for distances small compared to the earth radius).

For bigger x this funny page might help:
http://www.opensky.ca/~jdhildeb/arctan/arctan_taylor.html
or simply this:
arctan(x) = + pi /2 - arctan(1/x) // if (x > +1)
arctan(x) = - pi /2 - arctan(1/x) // if (x < -1)
 
S

Simon Brooke

Simon Brooke said:
Thanks, that sounds like an excellent suggestion.

And, indeed, it did help me to understand how I'd misunderstood Fred
Kleinschmidt's solution. I'm now getting results which agree to within one
ten millionth of a degree, which I think is good enough!

Thanks to everyone who contributed, but especially to Patricia and Fred.
The midlet as it stands is currently downloadable from

http://www.jasmine.org.uk/~simon/tmp/pointbeat_client.jad

- there's still a lot of bugs in it, and it assumes your GPS is on com7.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top