问题
Can anyone point me to a good example of Atan2 defined in C# (or something vaguely close to C#) that doesn't use any internal math methods? This is on .NET Microframework, so there is no such thing as an internal math library. I have already defined Sin()/Cos(), but I am having a lot of trouble with Atain2.
There are a few scatter shot math libraries in NETMF, but I have found them all to be flawed or broken. One of the major ones didn't even define PI correctly!
回答1:
An implementation should be quite straight forward starting with the definition on Wikipedia/atan2 and then using the infinite series expansion of arctan on Wikipedia.
Just sum up terms in the series until the last term is small enough for your application.
The error is less then the last term since it is an strictly decreasing function.
Edit:
Since you´re on the .NET Micro framework you might be low on computational resources. Depending on your required precision you might consider precalculating a table of the cos, sin, atan2, etc values and just use a simple lookup of the closest value. On the other hand this wastes some memory if you need too high precision.
回答2:
Have you considered/tried implementing the CORDIC algorithm? It will allow you to implement the atan function, from which it is easy to generate the atan2 function.
For the CORDIC algorithm, a description is at Wikipedia and better details are in this paper. Also, I see a GPL C++ version of CORDIC at the sourceforge code of the Signal Processing using C++ (SPUC) project. It includes the math library, but could be altered to avoid doing so. There is a convenient code listing on koders if you want to see the code.
If you are not concerned with speed, given any implementation of atan(z) that returns values between -pi/2 and pi/2 (or -90 and 90), you can implement atan2(y,x) returning values between 0 and 2pi (or 360) easily. Here is example pseudocode:
atan2(y,x){
if (x < 0){
return (atan(y/x)+3*pi/2); // subst 270 for 3*pi/2 if degrees
}else{
return (atan(y/x)+pi/2); // subst 90 for pi/2 if degrees
}
}
回答3:
This is Pascal implementation with fixed point numbers if ArcTan is already implemented:
function Fix64ArcTan2(const y, x: fix64): fix64;
// based on http://en.wikipedia.org/wiki/Atan2
// Variation of the arctangent function. For any real arguments x and y not both
// equal to zero, arctan2(x,y) is the angle in radians between the positive x-axis
// of a plane and the point given by the coordinates (x,y) on it.
var
result: fix64;
begin
if x = 0.0 then
if y = 0.0 then
result := 0.0; // ArcTan2(0,0) is undefined, but I had to return something !!!
elsif y > 0.0 then
result := FIX_PIHALF;
else // y < 0.0
result := -FIX_PIHALF;
endif;
else
result := Fix64ArcTan(Fix64Div(y,x));
if x < 0.0 then
if Y < 0.0 then
result := result - FIX_PI;
else // y >= 0.0
result := result + FIX_PI;
endif;
endif;
if result > FIX_PI then
result := result - FIX_PITWO;
endif;
endif;
return(result);
end;
回答4:
What board are you using. The GHI guys have the GHI....System namespace which defines MathEx with all the missing Math functions.
Sorry for not supplying links, but I'm at work so don't have access to my .NET MF Code at home.
Hope that helps.
Regards
来源:https://stackoverflow.com/questions/4162232/atan2-in-c-sharp-or-similar-lanaguge