C# 中的 Atan2(或类似语言)

发布于 2024-10-02 14:07:51 字数 199 浏览 10 评论 0原文

谁能给我指出一个用 C#(或隐约接近 C# 的东西)定义的 Atan2 的好例子,它不使用任何内部数学方法?这是在 .NET Microframework 上,因此不存在内部数学库之类的东西。我已经定义了 Sin()/Cos(),但是 Atain2 遇到了很多麻烦。

NETMF 中有一些散点数学库,但我发现它们都有缺陷或损坏。其中一个主要的甚至没有正确定义 PI!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

仅一夜美梦 2024-10-09 14:07:51

实现应该非常简单,从 Wikipedia/atan2 上的定义开始,然后使用 维基百科上 arctan 的无限级数展开

只需总结该系列中的项,直到最后一项对于您的应用来说足够小。
误差小于最后一项,因为它是严格递减函数。

编辑:
由于您使用的是 .NET Micro 框架,因此您的计算资源可能不足。根据您所需的精度,您可能会考虑预先计算 cos、sin、atan2 等值的表,然后仅使用最接近值的简单查找。另一方面,如果您需要太高的精度,这会浪费一些内存。

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.

柳絮泡泡 2024-10-09 14:07:51

您是否考虑/尝试过实施 CORDIC 算法?它将允许您实现 atan 函数,从中可以轻松生成 atan2 函数。

对于 CORDIC 算法,维基百科有描述,更好的详细信息请参见本文。另外,我在使用 C++ 的信号处理的 sourceforge 代码中看到了 GPL C++ 版本的 CORDIC ( SPUC)项目。它包括数学库,但可以进行更改以避免这样做。如果您想查看代码,koders 上有一个方便的代码列表

如果您不关心速度,则给定返回 -pi/2 和 pi/2(或 -90 和 90)之间的值的 atan(z) 的任何实现,您可以实现 atan2(y,x) 返回 0 和 0 之间的值轻松 2pi(或 360)。这是示例伪代码:

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
    }
}

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
    }
}
破晓 2024-10-09 14:07:51

如果 ArcTan 已经实现,那么这是具有定点数的 Pascal 实现:

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;

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;
停顿的约定 2024-10-09 14:07:51

你用的是什么板子。 GHI 人员拥有 GHI....System 命名空间,它定义了 MathEx 以及所有缺少的 Math 函数。

很抱歉没有提供链接,但我在工作,因此无法在家访问我的 .NET MF 代码。

希望有帮助。

问候

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文