Use atan2 function instead of atan – EasyHack
When working with shapes and charts in LibreOffice, there are several occasions that you have to calculate tan-1x. But is atan function always the best choice? Here we discuss using atan2 function instead of atan in C++ code.
When used in correct place, atan2 can have a lot of benefits when calculating atan ( y / x ).
If you use atan(x) to calculate the output θ, you have to think about different situations that may occur, because with the same value of x, there are multiple values of θ, and it would be your responsibility to handle that, and find out what is the suitable value of θ.
But, if you have two values y and x, and you want to calculate atan(y / x), there is a better choice: using atan2(y, x). As discussed here, atan2(y, x) can handle the values from all the 4 different quadrants.
This is the formula for atan2(y, x):
In this way, you don’t have to check the sign of x and y because atan2() does this by itself.
There are some places in the LibreOffice core that is currently using atan, and atan2 is more suitable. For example, in hwpfilter/source/hcode.cxx:
1447 double angle; 1448 angle = (180 / PI) * atan( ( y2 - y1 ) * 1.0 / ( x2 - x1 )); 1449 if( y2 >= y1 ){ /* 1, 2 quadrant */ 1450 if( angle < 0. ) 1451 angle += 180.; 1452 } 1453 else{ /* 3, 4 quadrants */ 1454 if( angle > 0 ) 1455 angle += 180.; 1456 else 1457 angle += 360.; 1458 }
A better choice would be this one single line:
1458 double angle = basegfx::rad2deg(atan2(y2 - y1 , x2 - x1));
Instead of multiplying the output of atan() by (180 / PI) to get degrees out of radians, we simply use basegfx::rad2deg() for the conversion, and also using the atan2(), those conditions would be superfluous, and are removed.
Finding instances of atan to replace with atan2
This grep command shows the instances of the similar situations:
git grep atan\(
Within the results of the grep, you can find places that atan2() is better. You should take care about the conditions that may be present (or missing) after the atan(). These conditions usually check the sign of the numerator and denominator in the fraction passed to atan(). Make sure that the code works correctly after removing them.
Final Notes
Besides fixing the bugs, there are many places to work on improving the code, and some of these are listed as EasyHacks. The specific improvement that is discussed in this blog post is filed as tdf#145630, and you can submit patches for this improvement to LibreOffice Gerrit.
If you want to work on this improvement, but you need to know how to get started with LibreOffice development, I suggest you to see our video tutorial: