2012-06-20 38 views
4

我需要幫助,使我的代碼更高效,並將其清理一點。如何使三角代碼更有效

如此image所示,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 

回答

6

看到這個http://www.cplusplus.com/reference/clibrary/cmath/atan2/爲C函數。

atan2需要2個獨立的參數,因此可以確定象限。

帕斯卡可能有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)); 
+0

非常感謝您的幫助,是的,確切的功能存在,它完美的工作(一旦我拿出'Abs()')。 – putonajonny

+1

我拿出了腹肌,對錯誤抱歉。 –

3

的代碼行數不一定是你需要考慮的唯一優化。對於單個函數完成其計算所花費的時間而言,三角函數代價很高(即:根據實現,單個cos()調用可能需要數百次的加法和乘法運算)。

對於信號處理中常用的函數,離散傅里葉變換,數千個cos()和sin()計算的結果被預先計算並存儲在一個大規模查找表中。權衡是在運行應用程序時使用更多內存,但速度更快。

請參閱以下文章,或搜索「預計算旋轉因子」的重要性,這實質上意味着提前計算大量複雜指數。在未來,您還應該提及您正在嘗試優化的內容(例如:使用的CPU週期,使用的內存字節數,成本等)。我只能假設你的意思是根據執行的指令進行優化,最後是所用的CPU週期數(即:要減少CPU開銷)。

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

+1

非常感謝,你給了我很多想法和展望。 – putonajonny

1

你應該只需要一個測試,以確定如何處理反正切做..你現有的測試收回Abs()破壞的信息。

atan()通常返回範圍-pi/4到pi/4。您的座標系有點奇怪 - 順時針旋轉90度即可獲得「標準」一個,但您需要atanx/y而不是y/x。我已經很難解決這個問題了。無論如何,我相信你的測試只需要,如果你在負面a,增加180度。如果你想避免消極的角度;如果此時爲負,則加360度。

+0

感謝您的幫助,它看起來像是x/y的原因是因爲我想要的垂直軸的角度不是橫軸的角度,是的我正在銷燬使用'Abs()'的信息,這就是爲什麼我知道這是低效的。 – putonajonny

+0

是的,我想到了當我考慮..哦,對面和相鄰。我看到他在那裏做了什麼。 – zebediah49