Hey so i'm doing some graphics math and inserting what i believe to be a float (i'm pretty sure the ways i manipulate the float beforehand is messing something up somehow...) into the function and getting strange, negative results back.
for instance when doing the following opperations when Angle initially equals 350.0, test ends up being
-.99. Why?
Angle= (float)(Angle-(int)Angle)+(float)((int)Angle%90);
// calculates x and y based on angle and Hypotenuse
float test= sin(Angle);
float test2= 1/(Speed*Time);
float test3= test/test2;
buffX= sin(Angle)/ (1.f/(Speed*Time));
buffY= sin(Angle-90)/ (1.f/(Speed*Time));
trying to keep Angle a float by putting (float) before everything didn't work... please help! Thanks!
That's because the C/C++ runtime function sin() expects the argument in radians, not degrees.
Convert to radians with:
float test= sin(Angle / 180 * M_PI);
etc.
sin takes its arguments in radians, not degrees. You need to take you number and multiply it pi/180
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 have the following function to convert from radians to degrees:
float DegreesToRadians(float degrees) {
return degrees * (PI / 180);
}
When I now do:
sinf(DegreesToRadians(90));
This returns 1, as expected.
But when I do:
sinf(DegreesToRadians(180));
It returns -8.74228e-08. Does anybody know why this is happening? (This happens with cosf too, but in reverse: 180 -> -1; 90 -> -8.74228e-08)
Well, your PI is an approximation of the real mathematical constant. Then your degree-to-radian conversion is an approximation of the real conversion because floating point math is an approximation. And then, the standard sinf function approximates the sin function in math. Thus, you should expect your results to be approximate. -8.74228e-08 is a number close to 0. It's an approximation.
How do I convert degrees to radians?
OP's degrees to radians conversion is reasonable.
return degrees * (PI / 180);
when I do: sinf(DegreesToRadians(180)); It returns -8.74228e-08.
This does not meet OP's expectations as degrees * (PI / 180) was not done exactly given PI is not π #Andy Turner. PI is machine pi, a nearby representable value of π. π is an irrational number. All finite floating point values are rational. There is no way to do non_zero_degrees * (π / 180) exactly. The error in the approximations are amplified in the sinf() call.
sinf(DegreesToRadians(180)) does not result in sine(π), but sine(PI). PI is close to π, but not the same. double graphical example.
Instead, reduce the range of of the angle in degrees first to maintain accuracy with trigonometric identities.
Example
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)
I'm getting some strange behavior using COS() and SIN() libraries in Fortran 77. It picks what number to perform it's operation on like here :
DATA V , THETA , PI / 100 , 45 , 3.1416 /
THETA = THETA * PI/ 180.0
PRINT *, "THETA = " , THETA
VX = V * COS ( THETA )
VY = V * SIN ( THETA )
PRINT *, VX , VY
END
when i check it, i find that
COS(THETA) = COS(45)
not
COS(0.7853)
and the same goes to SIN() too. So why does this happen ?
This is my output :
THETA = 0.785400
70.7105 70.7108
Those are the correct results. You're taking the cos of 45 degrees (converted to radians) and multiplying it by 100, and the cos of 45 degrees (or pi/4 radians) is 0.7071067, and so the expected value to print out is 70.7106.
SIN and COS functions take the arguments in radians. You use the correct formula to convert the input values from degrees to radians, and it's giving you the correct results for those converted values.
I'm curious how you could do the right conversion, and not realize that you did the right thing and got the right answer. Did you take this code from somewhere else?
I am trying to optimize the simulation function in my experiment so I can have more artificial brain-controlled agents running at a time. I profiled my code and found out that the big bottleneck in my code right now is computing the relative angle from every agent to every agent, which is O(n2), minus some small optimizations I have done. Here is the current code snippet I have for computing the angle:
[C++]
double calcAngle(double fromX, double fromY, double fromAngle, double toX, double toY)
{
double d = 0.0;
double Ux = 0.0, Uy = 0.0, Vx = 0.0, Vy = 0.0;
d = sqrt( calcDistanceSquared(fromX, fromY, toX, toY) );
Ux = (toX - fromX) / d;
Uy = (toY - fromY) / d;
Vx = cos(fromAngle * (cPI / 180.0));
Vy = sin(fromAngle * (cPI / 180.0));
return atan2(((Ux * Vy) - (Uy * Vx)), ((Ux * Vx) + (Uy * Vy))) * 180.0 / cPI;
}
I have two 2D points (x1, y1) and (x2, y2) and the facing of the "from" point (xa). I want to compute the angle that agent x needs to turn (relative to its current facing) to face agent y.
According to the profiler, the most expensive part is the atan2. I have Googled for hours and the above solution is the best solution I could find. Does anyone know of a more efficient way to compute the angle between two points? I am willing to sacrifice a little accuracy (+/- 1-2 degrees) for speed, if that affects anything.
As has been mentioned in the comments, there are probably high-level approaches to reduce your computational load.
But to the question in hand, you can just use the dot-product relationship:
theta = acos ( a . b / ||a|| ||b|| )
where a and b are your vectors, . denotes "dot product" and || || denotes "vector magnitude".
Essentially, this will replace your {sqrt, cos, sin, atan2} with {sqrt, acos}.
I would also suggest sticking to radians for all internal calculations, only converting to and from degrees for human-readable I/O.
Your comment tells a lot: "I am simulating a 180 degree frontal retina for every agent, so I need the angle". No, you don't. You just need to know whether the angle between the position vector and vision vector is more or less than 90 degrees.
That's very easy: the dot product A·B is >0 if the angle between A and B is less than 90 degrees; 0 if the angle is precisely 90 degrees, and <0 if the angle is more than 90 degrees. Calculating this takes 3 multiplications and 2 additions.
i think it's more a mathematical problem:
try
abs(arctan((y1-yfrom)/(x1-xfrom)) - arctan(1/((y2-yfrom2)/(x2-xfrom2))))
Use the dot product of these two vectors and at worst you need to do an inverse cosine instead:
A = Facing direction. B = Direction of Agent Y from Agent X
Calculating the dot is simple multiplication and addition. From that you have the cosine of the angle.
For starters, you should realize that there are a couple of simplifications that can reduce the calculations a bit:
You need not calculate the angle from an agent to itself,
If you have the angle from agent i to agent j, you already know something about the angle from agent j back to agent i.
I have to ask: what does "agent i turn to face agent j" mean? If the two surfaces are looking right at each other, do you have to do a calculation? What tolerance do you have on "looking right at each other"?
It'd be easier to recommend what to do if you'd stop focusing on the mathematics and describe the problem more fully.