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;

代码是帕斯卡,但用其他类似语法或 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
4

3 回答 3

6

有关 C 函数,请参阅此http://www.cplusplus.com/reference/clibrary/cmath/atan2/

atan2 采用 2 个单独的参数,因此可以确定象限。

pascal 可能有 arctan2 参见http://www.freepascal.org/docs-html/rtl/math/arctan2.htmlhttp://www.gnu-pascal.de/gpc/Run-Time-System.html

o := MiddleOfScreenX - x;
a := MiddleOfScreenY - y;

t := Degrees(ArcTan2(o, a));
于 2012-06-20T21:19:15.407 回答
3

代码行数不一定是您需要考虑的唯一优化。就单个函数完成其计算所需的时间而言,三角函数的成本很高(即:单个 cos() 调用可能需要数百次加法和乘法,具体取决于实现)。

对于信号处理中常用的函数离散傅里叶变换,数千次 cos() 和 sin() 计算的结果被预先计算并存储在海量查找表中。权衡是在运行应用程序时使用更多内存,但运行速度要快得多。

请看下面的文章,或者搜索“预先计算的旋转因子”的重要性,这本质上意味着预先计算出大量的复指数。

将来,您还应该提及您正在尝试优化的内容(即:使用的 CPU 周期、使用的内存字节数、成本等)。我只能假设您的意思是在执行的指令方面进行优化,并且通过扩展,使用的 CPU 周期数(即:您想减少 CPU 开销)。

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.9421&rep=rep1&type=pdf

于 2012-06-20T21:28:00.073 回答
1

您应该只需要一项测试来确定如何处理 arctan .. 您现有的测试恢复了被破坏的信息Abs()

atan()通常在 -pi/4 到 pi/4 的范围内返回。你的坐标系有点奇怪——顺时针旋转 90 度以获得“标准”坐标系,尽管你取atanx/yy/x. 我已经很难在脑海中解决这个问题了。

无论如何,我相信你的测试只需要是如果你是负数a,增加 180 度。如果你想避免负角;如果它是负数,则添加 360 度。

于 2012-06-20T21:30:39.423 回答