I am trying to do a simple trigonometric calculation in C++. The following is an example of the problem I am having with this. As far as I know, C++ works in radians, not degrees. So conversion from radians to degrees should be a simple case of multiplying by 180 and dividing by pi. A simple test is tan(45), which should equate 1. The following program produces a value of 92.8063 however...
#include <iostream>
using namespace std;
#include <math.h>
int main(){
double a,b;
a = tan(45);
b = a * 180 / 3.14159265;
cout << b;
return 0;
}
What is wrong?
You're doing it backwards. Don't apply the formula to the output of tan, apply it to the parameter.
Also you'll want to multiply by pi and divide by 180, not vice versa.
The angle is the input to tan. So you want:
a = 45 * 3.141592653589793 / 180.0;
b = tan(a);
cout << b << endl;
You must pass radians to the tan function. Also degrees to radian is wrong.
a = tan(45 * 3.14159265 / 180.);
Tan accepts an angle, and returns a quotient. It is not the other way around. You want
a = tan(45*3.14159265/180); // Now a is equal to 1.
Related
For example I have a value 0.70, and it is a sin() for 45 degrees. I need a function, that will calculate me an angle from a sin. What function from C++ can help me?
You can use std::asin. This returns a value between [-PI/2,+PI/2], to get degrees you multiply by 180 and divide by PI.
result = std::asin(value) * 180 / PI
PI = 3.1415926535
I'm building a small Physics engine and I'm having trouble converting my Radian value to Degrees using atan, as I need an angle to output in Degrees only.
Firstly, I have an x and y value, and I need to find an angle using atan, so I divide y by x like so:
angleDivide = yN / xN;
Then, before putting this value into tan, I attempt to convert it to Degrees like this:
angleToDegrees = angleDivide * (3.14 / 180);
Then I place angleToDegrees into atan:
angle = atan(angleToDegrees);
But when I'm displaying angle, I'm, still getting radian values.
Please could you tell me what is wrong with my code and how to fix this?
You want to calculate radians=tan(y/x) first.
Then you can convert it to degrees:
radians = atan(y/x)
degrees = radians * (180.0/3.141592653589793238463)
See the reference here for atan:
On a side note, you also have to take into account what quadrant you are in to get the correct answer (since -y/x is the same number as y/-x)
Suppose that I have a 3-dimensional frame with rotation roll = 0, pitch = 0 and yaw = 0 about x, y and z axis respectively.
I want the frame to rotate about x-axis for 3.14159 (Pi) or roll = Pi.
Below is the code for said situation.
The problem is, when I want to convert the rotation matrix back to roll, pitch, and yaw, the code gives different answer.
Instead of roll = Pi, the result is roll = 0, pitch = pi, and yaw = pi.
I think RVC toolbox by Peter Corke on Matlab gives correct answer.
Maybe something is not right with with my program or eulerAngles in Eigen works differently? Please help.
Code:
#include <iostream>
#include <Eigen/Dense>
const double PI = 3.14159265359;
int main()
{
using ::Eigen::AngleAxisd;
using ::Eigen::Matrix3d;
using ::Eigen::Vector3d;
using ::std::cout;
using ::std::endl;
Matrix3d R,Rx;
R = AngleAxisd(PI, Vector3d::UnitX())
* AngleAxisd(0, Vector3d::UnitY())
* AngleAxisd(0, Vector3d::UnitZ());
Rx = AngleAxisd(PI, Vector3d::UnitX());
cout << R << endl << endl;
cout << Rx << endl << endl;
Vector3d ea = R.eulerAngles(0,1,2);
Vector3d eax = Rx.eulerAngles(0,1,2);
cout << ea << endl << endl;
cout << eax << endl << endl;
std::cin.ignore();
return 0;
}
Output (I round off numbers which are too small to zero):
1 0 0
0 -1 0
0 0 -1
1 0 0
0 -1 0
0 0 -1
0
3.14159
3.14159
0
3.14159
3.14159
Euler's angles are not unique. In your XYZ convention, both (0, pi, pi) and (pi,0,0) represents the same rotation, and both are correct. The Eigen::eulerAngles method consistently chooses to minimize first angles.
Please refer to the documentation of Eigen:eulerAngles. Details on various conventions of Euler-angles is well documented in Wikipedia and MathWorld.
Edit:
You will get exact results if you use M_PI, which is internally defined, instead of truncated value of PI.
The Euler-angle representation suffers from singularity. The test case that you are trying to compare is a singular position.
You may want to use quaternions or axis-angle representation if you wish to overcome the singularities.
Different order euler angles(roll1, pitch1, yaw1 or pitch2, yaw2, roll2, ...) can result in the same rotation matrix.
Actually, the Eigen document gave the answer.
Read the function declaration of Eigen document more carefully, and you will get the answer.
Matrix< typename MatrixBase< Derived >::Scalar, 3, 1 > Eigen::MatrixBase< Derived >::eulerAngles ( Index a0,
Index a1,
Index a2
) const
Each of the three parameters a0,a1,a2 represents the respective rotation axis as an integer in {0,1,2}. For instance, in:
Vector3f ea = mat.eulerAngles(2, 0, 2);
"2" represents the z axis and "0" the x axis, etc
My exercise is to write code which will print the value of this phrase
I have written a code which should work, but when I try to print a value I receive "the value is -nan".
//My Code
#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
int main()
{
double y;
double x = 21;
y = 30 * sqrt(x * (1/(tan(sqrt(3*x) - 2.1))));
printf ("The value is: \n=> %f", y );
}
My question is how can I print the proper value?
try this
printf( "sqrt(3*x) = %lf\n", sqrt(3*x));
printf( "sqrt(3*x) - 2.1 = %lf\n", sqrt(3*x) - 2.1);
printf( "tan(sqrt(3*x) - 2.1) = %lf\n", tan(sqrt(3*x) - 2.1));
then you will notice that the last one is negative which will result in a sqrt of a negative number, thus the NaN
The problem is that, depending on the unit (radians or degrees), you get different results with trigonometric functions. Keep in mind that the tan function expects its argument in radians.
sqrt(3*21)-2.1 = 5.837, and you have to calculate its tangent. It is indeed negative if we work with radians (it is around -0.478), leading to the square root of a negative number which is NaN (Not a Number), but if you use degrees then it is +0.102 and you can complete the calculation. If you want to have the result you would have with degrees, considering the function accepts radians, you must convert the number. The conversion is simple: multiply by Pi and divide by 180. Like this:
y = 30 * sqrt(x * (1/(tan((sqrt(3*x) - 2.1)*M_PI/180))));
In this case the result is 429.967.
If the problem is not related with conversion to radians, i.e. multiplication by M_PI / 180.
In general, operations that produce NaN (Not a Number)1 are:
In your case the result of tan() is negative which leads to negative input value for the outer sqrt(), which is the last example from the above table.
To resolve the problematic situation you could either use some mathematical trick2 and try to rewrite the expression such that it doesn't produce a NaN, or if the problem is in the negative square root, you can use the #include <complex> and:
std::complex<double> two_i = std::sqrt(std::complex<double>(-4));
The rest of the answers provide you with a strategy of how to identify the NaN source, by checking each computation involved
1. Bit patterns reserved for special quantities to handle exceptional situations like taking the square root of a negative number, other than aborting computation are called NaNs.
2. Use trigonometric relations.
where #define M_PI = 3.14159265358979323846;
So I was trying to puzzle out how to calculate the average hue of a number of objects whose colors are represented by HSL values. Thankfully, I stumbled across this Stack Overflow post, and set to work implementing the algorithm provided in the top answer (I am working in C++).
Unfortunately, my implementation doesn't seem to work. Here it is, in full; note that though I write "Hue" I am using angles, in degrees, as per the initial implementation (switching from 0-360 angles to 0-256 hues, once I know my code works, shouldn't be hard).
#include <iostream>
#include <vector>
#include <cmath>
#define PI (4*atan(1))
int main()
{
///
/// Calculations adapted from this source:
/// https://stackoverflow.com/questions/8169654/how-to-calculate-mean-and-standard-deviation-for-hue-values-from-0-to-360
std::vector<double> Hues = {355, 5, 5, 5, 5};
//These will be used to store the sum of the angles
double X = 0.0;
double Y = 0.0;
//Loop through all H values
for (int hue = 0; hue < Hues.size(); ++hue)
{
//Add the X and Y values to the sum X and Y
X += cos(Hues[hue] / 180 * PI);
Y += sin(Hues[hue] / 180 * PI);
}
//Now average the X and Y values
X /= Hues.size();
Y /= Hues.size();
//Get atan2 of those
double AverageColor = atan2(X, Y) * 180 / PI;
std::cout << "Average: " << AverageColor << "\n";
return 0;
}
Instead of the expected answer of 3 (since 355 should be equivalent to -5 in this scheme), I get 86.9951.
Can somebody point out what I'm doing wrong? This seems very basic.
atan2 takes its arguments in reverse order. I know, annoying! So try:
double AverageColor = atan2(Y, X) * 180 / PI;
The answer it gives now is 3.00488.
Try atan2(Y, X). atan2(a,b) is similar to atan(a/b), and you need the arctangent of the average sine over the average cosine.