如何使三角函数代码更高效

4
我需要帮助让下面的代码更高效,并使其更加简洁。
如此图像所示,x和y可以是屏幕上任何点,我正在尝试找到角度t。有没有办法减少这里的行数?
注意:原点在左上角,向右/向下移动是正方向。
o := MiddleOfScreenX - x;
a := MiddleOfScreenY - y;

t := Abs(Degrees(ArcTan(o / a)));

if(x > MiddleOfScreenX)then
  begin
    if(y > MiddleOfScreenY)then
      t := 180 + t
    else
      t := 360 - t;
  end
else
  if(y > MiddleOfScreenY)then
    t := 180 - t;

这段代码是用Pascal编写的,但使用类似语法的其他语言、C++或Java也可以。

:= sets the variable to that value
Abs() result is the absolute of that value (removes negatives)
Degrees() converts from radians to degrees
ArcTan() returns the inverse tan
3个回答

6

非常感谢您的帮助,确实存在那个准确的函数并且它完美地工作(一旦我去掉了 Abs())。 - putonajonny
1
我去掉了绝对值函数,对于这个 bug 感到抱歉。 - ctrl-alt-delor

3
代码行数并不一定是唯一需要考虑的优化因素。三角函数在计算时所需的时间成本较高(即:单个cos()调用可能需要进行数百次加法和乘法,具体取决于实现方式)。
对于信号处理中常用的一个函数——离散傅里叶变换,成千上万个cos()和sin()的结果被预先计算并存储在一个大型查找表中。这种权衡的代价是在运行应用程序时使用更多的内存,但它运行得 MUCH 更快。
请参阅下面的文章或搜索“预计算旋转因子”的重要性,这实际上意味着预先计算大量的复指数。
在未来,你还应该提到你正在尝试进行优化的内容(即:CPU周期使用、内存使用字节数、成本等等)。我只能假设你的意思是在执行指令方面进行优化,进而减少 CPU 开销。 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.9421&rep=rep1&type=pdf 请参考本文。

1
非常感谢您,您给了我很多值得思考和研究的内容。 - putonajonny

1

你只需要一个测试来确定如何处理arctan..你现有的测试可以恢复由Abs()破坏的信息。

atan()通常返回范围在-pi/4到pi/4之间。你的坐标系有点奇怪--顺时针旋转90度以获得一个“标准”的坐标系,尽管你取x/yatan而不是y/x。我已经很难在我的头脑中解决这个问题了。

无论如何,我相信你的测试只需要这样:如果你处于负数a,则添加180度。如果你想避免负角度,则添加360度,如果它仍然是负数。


感谢您的帮助,它看起来像是 x / y 的原因是因为我想要相对于垂直轴的角度而不是相对于水平轴的角度,是的,我在使用 Abs() 时破坏了信息,这就是为什么我知道它效率低下的原因。 - putonajonny
是的,当我考虑到……哦,对面和相邻时,我发现了这一点。我看到他在那里做了什么。 - zebediah49

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接