Nextion:计算没有三角函数或浮点的反 tan (arctan)

Nextion: Calculate inverse tan (arctan) without trig functions or floating point

提问人:ezra_vdj 提问时间:11/14/2023 最后编辑:ezra_vdj 更新时间:11/19/2023 访问量:58

问:

我正在对这个 Nextion 显示器上的接口进行编程。具体来说,我正在尝试对一个围绕中心点旋转的数字表盘进行编程。

这些屏幕很棒,但它们没有任何触发功能,它们没有浮点,也无法旋转图像。只是分享这些规格作为我约束的背景,不要担心屏幕。

我需要一种方法将 X,Y 坐标转换为 0-359 输出。

有谁知道使用整数数学来近似角度的任何技巧或窍门?

我现在所拥有的只是为每个四分位数调整的梯度,但它不是线性的,因为我只是在做上升/运行。

整数 三角学 整数除法 下位

评论


答:

1赞 jhole 11/14/2023 #1

有一篇论文 Efficient approximations for the arctangent function 描述了一个快速函数:atan

double FastArcTan(double x)
{
    return M_PI_4*x - x*(fabs(x) - 1)*(0.2447 + 0.0663*fabs(x));
}

这当然使用数据类型。double

用比例因子 10000 的定点算术重写(所以“(int) 10000”实际上意味着“1.0”),你可以写一个函数,这里作为完整的小测试程序:int IntArcTan(int x_scaled)

#include <stdio.h>
#include <math.h>

// -10000 < x_scaled < 10000; integer arithmetic i.e. (int)10000 means (float)1.0000
int IntArcTan(int x_scaled)
{
   int abs_x_scaled = x_scaled >= 0 ? x_scaled : -x_scaled;
   int a = 7854/* PI/4 */ * x_scaled / 10000;
   int b = x_scaled*(abs_x_scaled - 10000) / 10000;
   int c = b * 2447 / 10000;
   int d = b * 663 / 10000 * abs_x_scaled / 10000;

   return a - c - d;
}

int main()
{
   for (double x = -1.; x < 1.; x+=.01)
   {
      double   atan_std           = atan(x);
      int      atan_int_scaled    = IntArcTan((int)(x * 10000));
      double   atan_int           = (double)atan_int_scaled / 10000;
      printf("x = %10.3f, atan_std(x) = %10.3f, atan_int(x) = %10.3f, error = %10.3f%%\n", x, atan_std, atan_int, atan_int/atan_std*100-100);
   }
   
}

你只需要记住缩放你的定点算术变量(1.0 -> 10000),并且最终输出是以弧度为单位的,所以得到度数atanatan_int_scaled * 45 / 7854

0赞 ezra_vdj 11/15/2023 #2

谢谢你@jhole为我指出了arctan近似公式的方向。我最终对它进行了一些修改,以适应我的Nextion屏幕所需的内容,包括X和Y坐标的输入,以度为单位的输出,并且不会使变量太大而无法溢出(选择x10乘数以允许1位数字进行舍入)。

我能够使用这个输出度数的公式启动并运行它(来自 Desmos 的屏幕截图,其中“a”= 380 和“b”= 400):

enter image description here

“a”是 Y 坐标,“b”是 X 坐标。我在图片中加入了基准触发函数,您可以看到它非常接近。我希望结果是 10 倍乘以允许四舍五入,因为小数点以下的所有内容都会在 Nextion 上丢失。

我真的很想去掉前面的两个括号,把所有东西都减少到一个有一个除法的大部分,但我发现变量太大了,所以我发现这是速度和准确性的一个很好的甜蜜点。

在实现此公式时需要注意的关键事项是,它仅在 RISE <= RUN 且 'a' 和 'b' 均为正值时才有效。为了在顶部和底部四个 45 度段进行测量,我不得不翻转 RISE/RUN 变量。从那里,我能够根据您触摸的象限从 0,180,270,360 值中添加/减去。