Reputation: 1233
Let's say I have the values X = 0, Y = 0 and I want to calculate a new point (X1, Y1) from a vector and a magnitude. Let's say the vector is 90 degrees (not radians) and the magnitude is 10 so the code would look something like this:
x1 = X + (10 * Math.Cos(90 * (Math.PI / 180.0)));
y1 = Y + (10 * Math.Sin(90 * (Math.PI / 180.0)));
And I then draw a line to confirm the results
DrawLine(X,Y,x1,y1);
But my line is off by 90 degrees too much! If I subtract 90 from the angle that I'm passing to Cos and Sin everything works out fine. So, I guess, I can live with that.
Here's a screen shot:
I'm passing it 90 and I'm expecting the line to go west - east. I assume that 0 degrees is due north. I know that the coordinate system I'm using is X is horizontal and Y is vertical.
I'm just curious as to what I'm missing.
Upvotes: 0
Views: 2057
Reputation: 22038
I don't see any problem about the x and y.
You use COS for x. COS(0) = 1 , COS(90) = 0
You use SIN for y. SIN(0) = 0 , SIN(90) = 1
And for the screen coordinate system:
x+ is left to right
y+ is top to bottom
Thats why the line goes from top to bottom.
As you can see, the line isn't nice and straight. Follow the declaration of Math.PI and you will see: public const double PI = 3.14159
(I don't know whois responsible for this, but I would fire him). That isn't very accurate! Try to replace the PI with: 3.14159265358979323846
Makes:
public const double BETTER_PI = 3,14159265358979323846
x1 = X + (10 * Math.Cos(90 * (BETTER_PI / 180.0)));
y1 = Y + (10 * Math.Sin(90 * (BETTER_PI / 180.0)));
So:
x1 = X + (10 * Math.Cos(1.57079632679)) = X + (10 * 0) = X + 0;
y1 = Y + (10 * Math.Sin(1.57079632679)) = Y + (10 * 1) = Y + 10;
UPDATE:
As Chis says, the meta data is wrong. So use the Math.PI
Upvotes: 1
Reputation: 153358
Unexpected integer truncation
The conversion from degrees to radians resulted in a value near pi/2, but not exactly. (Hard to do as pi is transcendental.) Math.Cos(near_pi/2)
resulted in a value near 0.0, but not _exactly 0.0. Let's assume it was negative like -6.1e-17.
Assuming 'X' was a floating point number with an integer value, the result of X + small_negative_number
was a number just less than the integer value. Assigning that result to x1
and giving it to the plot()
routine, which certainly uses integer values caused a integer truncation down to the next lower integer.
Thus the expected straight line is 1 pixel off.
The general solution is to present plot(x,y)
with integer values that are derived from rounded floating point values.
x_int = round(X_floating_point);
Upvotes: 2