Calculating degrees fails![^].

Please don't re-post anymore.

See more:

Hello Codeproject,

Let's assume I have two vector points.

I have however attempted this:

But the result was:

[^]

Help please!

How would I do the above?

- Riberto

Let's assume I have two vector points.

```
/* Vectors to begin angle calculation. */
Vector2 PointStart = new Vector2(Room.Width / 2, Room.Height / 2);
Vector2 PointMouse = new Vector2(Mouse.X, Mouse.Y);
/* Set the angle. */
Angle = Angle.From(PointStart, PointMouse);
```

I have however attempted this:

```
/* Get Angle between void. */
/// <summary>
/// Retrieves the angle between two points(Vectors).
/// </summary>
/// <param name="i">The starting vector.</param>
/// <param name="j">The point to the other vector(12 o' clock)</param>
/// <returns></returns>
public float AngleToMouse(Vector2 Mouse)
{
/* Delta */
DeltaPoint = new Vector2((this.PositionX + Mouse.X) - this.PositionX, (this.PositionY + Mouse.Y) - this.PositionY);
/* Return */
return (float)(Math.Atan2(DeltaPoint.Y, DeltaPoint.X) * 180 / Math.PI);
}
```

But the result was:

[^]

Help please!

How would I do the above?

- Riberto

Comments

And what exactly is the issue and not working? I opened up the image but it did not say anything about the issue.

Oh, I didn't notice that there was no cursor. Anyways, my cursor is in the down left corner, and it's looking at the other side.

The computation of DeltaPoint look wrong. I'm not sure of what angle you want so it somewhat hard to answer.

I would use the scalar product formula, namely

Hence

`v1 . v2 = |v1| |v2| cos(phi)`

.Hence

`phi = arccos( x1*x2+y1*y2/sqrt(x1*x1+y1*y1)/sqrt(x2*x2+y2*y2))`

.```
public double Angle(Vector2 v1, Vector2 v2)
{
double v1m = Math.Sqrt(v1.X*v1.X+v1.Y*v1.Y);
double v2m = Math.Sqrt(v2.X*v2.X+v2.Y*v2.Y);
double angle = 180 * Math.PI * Math.Acos(( v1.X*v2.X+v1.Y*v2.Y ) / v1m / v2m);
return angle;
}
```

Comments

This returns as NaN?

It shouldn't. What are your input values?

public void DoMouse()

{

/* Mouse State */

MouseState State = Mouse.GetState();

/* Set the Angle. */

World.Player.SetAngle(World.Player.AngleBetweenCooardinates(new Vector2(State.X, State.Y), new Vector2(World.Player.PositionX, World.Player.PositionY)));

}

{

/* Mouse State */

MouseState State = Mouse.GetState();

/* Set the Angle. */

World.Player.SetAngle(World.Player.AngleBetweenCooardinates(new Vector2(State.X, State.Y), new Vector2(World.Player.PositionX, World.Player.PositionY)));

}

Carlo, you should use different expression, depending on quadrant. Even if the acos value is defined, it causes Loss of Presicion, if you do it wrong. You should first compare X*X with Y*Y and make a decision accordingly.

—SA

—SA

Are you kidding?

?

I've tested the formula with 10000 random inputs. It never produced a NaN.

" System.Windows.Forms.MessageBox.Show(Angle(new Vector2(Mouse.GetState().X, Mouse.GetState().Y), new Vector2(World.Player.GetPositionX(), World.Player.GetPositionY())).ToString());" Produces NaN.

Numbers:

PlayerX = 0;

PlayerY = 0;

MouseX = 130;

MouseY = 160;

I honestly don't understand how this is not a NaN for you, as NaN is an infinite loop, so something must be wrong with your code.

"In computing, NaN (Not a Number) is a value of the numeric data type representing an undefined or unrepresentable value, especially in floating-point calculations. Systematic use of NaNs was introduced by the IEEE 754 floating-point standard in 1985, along with the representation of other non-finite quantities like infinities."

Numbers:

PlayerX = 0;

PlayerY = 0;

MouseX = 130;

MouseY = 160;

I honestly don't understand how this is not a NaN for you, as NaN is an infinite loop, so something must be wrong with your code.

"In computing, NaN (Not a Number) is a value of the numeric data type representing an undefined or unrepresentable value, especially in floating-point calculations. Systematic use of NaNs was introduced by the IEEE 754 floating-point standard in 1985, along with the representation of other non-finite quantities like infinities."

That's fine: Player = {0,0} is a meaningless input.

You cannot find the angle with a vector having modulus equal to zero.

You cannot find the angle with a vector having modulus equal to zero.

Exactly, OP needs to check for that. But quadrant calculation is important for the accuracy. Say, you have really small angle. Cos of it is a bit less than 1. If you use the projection of vector to X, it's the cos value, so acos will be the angle calculated with very low accuracy. You should use sin; near zero, the sin and the projection of the vector is almost proportional to angle, giving the best accuracy.

Look at available implementations. For example, System.Numerics calculation of Complex.Arg uses the same algorithm, as Arg is an angle...

—SA

Look at available implementations. For example, System.Numerics calculation of Complex.Arg uses the same algorithm, as Arg is an angle...

—SA

What can I do? You are missing something very basic in numerical calculations.

I finally answered to the same question (by my mistake, to the re-posted one). Please see:

http://www.codeproject.com/Answers/552477/Calculatingplusdegreesplusfails#answer2.

—SA

I finally answered to the same question (by my mistake, to the re-posted one). Please see:

http://www.codeproject.com/Answers/552477/Calculatingplusdegreesplusfails#answer2.

—SA

You might do a test, like I did (I've found NO appreciable difference between the two methods).

(Sigh...)

?!

Tested I, tested, long time ago... In mathematics, the truth is established not by testing, but by the proof...

—SA

—SA

Well you are wrong.

We aren't playing mathematics here, we are programming.

The same happens in physics: theory is nothing without experimental proof.

We aren't playing mathematics here, we are programming.

The same happens in physics: theory is nothing without experimental proof.

No, no, just stop it. This is professional, and profession is nothing but a limitation. And I can proof my point, and your experiment is just insufficient. Truth is truth, everything else is just excuses. If you don't know that "experiment proofs nothing", you know nothing about experiments.

As I understand you don't question that I use a correct approach, you only insist that yours is also correct, right?

—SA

As I understand you don't question that I use a correct approach, you only insist that yours is also correct, right?

—SA

No, I question everything you said, because it is plain wrong.

Did you see my solution?

—SA

—SA

Yes.

OK then. You are starting to behave emotionally, with no evidence or proof. Perhaps it's a time to stop it...

—SA

—SA

Time to stop , definitely. That's just nonsense. Axiomatic nonsense.

One minute. Actually, I've just written a comparison code which clearly shows that you Acos gives up to some 100% error at certain angles (as well as Asin at angles moved by 90 degrees). In contrast, using Atan2 (not Atan, but Atan2!) always gives good results, because this method avoids using this loss-of-precision point and make a choice based on both projection of a vector. I'm sure you did not try my solution.

I'm sure you are a honest person, so you will have to recognize this proof. As a physicist, you are supposed to know about loss-of-precision problem, and inadequate accuracy of Acos and Atan. As sin/cos signals are fundamental in physics, this should be a common place. I knew about this problem well before I entered the university.

That would be a really constructive dialog, and, by the way, useful for the readers.

How about that?

—SA

I'm sure you are a honest person, so you will have to recognize this proof. As a physicist, you are supposed to know about loss-of-precision problem, and inadequate accuracy of Acos and Atan. As sin/cos signals are fundamental in physics, this should be a common place. I knew about this problem well before I entered the university.

That would be a really constructive dialog, and, by the way, useful for the readers.

How about that?

—SA

Could you please show one of the mismatching outputs?

Of course. Let's work with doubles.

Take the angle x = 17.0e-9 radians, calculate its acos(cos(x)), which is a round trip, should get you the same x, but you will get 12% error.

Take x = 20.0e-9, it will give you the error 5.4%

Take x = 9.0e-9 or less, acos jumps to 0, so error jumps to 100%.

Equivalent operations with asin always give you 0% error is such round trip, for any angles close to X axis (up to += 45 degrees to it).

You can easily check it up. Only don't tell me that such small angles does not matter. Algorithms should work for any applications, and for some, such angles are used. This can be phase shift, complex number argument, anything like that.

For vector angles close to the coordinate axes, correct value is given by acos or asin, but never both. That's why atan2 is invented, it automatically chooses the calculation route for optimal precision.

This is a well known issue. If I'm not much mistaken, scientific calculators of my childhood came with warning about asin and acos accuracy (and maybe something else).

The nature of this error is pretty much the same as accuracy loss when you subtract to big numbers. I've shown the case when the lengths of the vector and its x-projection are very close...

—SA

Take the angle x = 17.0e-9 radians, calculate its acos(cos(x)), which is a round trip, should get you the same x, but you will get 12% error.

Take x = 20.0e-9, it will give you the error 5.4%

Take x = 9.0e-9 or less, acos jumps to 0, so error jumps to 100%.

Equivalent operations with asin always give you 0% error is such round trip, for any angles close to X axis (up to += 45 degrees to it).

You can easily check it up. Only don't tell me that such small angles does not matter. Algorithms should work for any applications, and for some, such angles are used. This can be phase shift, complex number argument, anything like that.

For vector angles close to the coordinate axes, correct value is given by acos or asin, but never both. That's why atan2 is invented, it automatically chooses the calculation route for optimal precision.

This is a well known issue. If I'm not much mistaken, scientific calculators of my childhood came with warning about asin and acos accuracy (and maybe something else).

The nature of this error is pretty much the same as accuracy loss when you subtract to big numbers. I've shown the case when the lengths of the vector and its x-projection are very close...

—SA

OK, I made a test with two vectors having your critical angle. My method indeed returns 0 while your, correctly, returns 9e-9. Of course the test is related to the OP question (this is the right context, I was answering it) so, assuming one of the vector along the X axys, I had to set its length to be

`111111111`

pixels (remember one of the vector is given by the mouse pointer). Now I challenge you to find such a screen. Did you see why I were talking about 'reality'? In this context the accuracy difference between the two methods is completely irrelevant.Carlo, I call it all excuses. Algorithms should be applied to all application. And discussion makes no sense, because the perfect solution already exists: using Atan2.

Look at the source code of Complex argument.

You just don't know what else to say...

—SA

Look at the source code of Complex argument.

You just don't know what else to say...

—SA

Do you apply general relativity to find out how many seconds the stone will take to reach the bottom of the well?

You are out of touch with reality, definitely.

Well, irrelevant... Atan2 is not complication, unlike relativity.

If you want to tell me excuses, it's not interesting...

—SA

If you want to tell me excuses, it's not interesting...

—SA

I don't need to tell you excuses (you are not in such a position).

General Relativity could be a complication, but it is (so far) the perfect algorithm.

Still I feel I answered correctly and your arguments are irrelevant to the original question. Anyway, now I'm quite tired of this discussion: I suppose there is no insight the OP (or other readers) can gain from it. So I'm going to quit.

General Relativity could be a complication, but it is (so far) the perfect algorithm.

Still I feel I answered correctly and your arguments are irrelevant to the original question. Anyway, now I'm quite tired of this discussion: I suppose there is no insight the OP (or other readers) can gain from it. So I'm going to quit.

Sure, let's stop it.

Thank you for the discussion anyway.

:-)

—SA

Thank you for the discussion anyway.

:-)

—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject,
503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada
+1 416-849-8900 x 100