简体   繁体   中英

How to make trigonometry code more efficient

I need help to make my code below more efficient, and to clean it up a little.

As shown in this image , x and y can be any point around the whole screen, and I am trying to find the angle t. Is there a way I can reduce the number of lines here?

Note: The origin is in the top left corner, and moving right/down is moving in the positive direction

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;

The code is in pascal, but answers in other languages with similar syntax or c++ or java are fine as well.

:= 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

see this http://www.cplusplus.com/reference/clibrary/cmath/atan2/ for a C function.

atan2 takes 2 separate arguments, so can determine the quadrant.

pascal may have arctan2 see http://www.freepascal.org/docs-html/rtl/math/arctan2.html or http://www.gnu-pascal.de/gpc/Run-Time-System.html

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

t := Degrees(ArcTan2(o, a));

The number of lines of code isn't necessarily the only optimization you need to consider. Trigonometric functions are costly in terms of the time it takes for a single one to finish its computation (ie: a single cos() call may require hundreds of additions and multiplications depending on the implementation).

In the case of a commonly used function in signal processing, the discrete Fourier transform, the results of thousands of cos() and sin() calculations are pre-calculated and stored in a massive lookup table. The tradeoff is that you use more memory when running your application, but it runs MUCH faster.

Please see the following article, or search for the importance of "precomputed twiddle factors", which essentially means calculating a ton of complex exponentials in advance.

In the future, you should also mention what you are trying to optimize for (ie: CPU cycles used, number of bytes of memory used, cost, among other things). I can only assume that you mean to optimize in terms of instructions executed, and by extension, the number of CPU cycles used (ie: you want to reduce CPU overhead).

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

You should only need one test to determine what to do with the arctan.. your existing tests recover the information destroyed by Abs() .

atan() normally returns in the range -pi/4 to pi/4. Your coordinate system is a bit strange--rotate 90 deg clockwise to get a "standard" one, though you take atan of x/y as opposed to y/x . I'm already having a hard time resolving this in my head.

Anyways, I believe your test just needs to be that if you're in negative a , add 180 deg. If you want to avoid negative angles; add 360 deg if it's then negative.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM