Click here to Skip to main content
13,042,819 members (63,401 online)
Rate this:
Please Sign up or sign in to vote.
See more:
Hello Codeproject,

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
Posted 24-Feb-13 3:44am
Yvar Birx2.4K
Updated 24-Feb-13 4:23am
Sandeep Mewara 24-Feb-13 11:15am
And what exactly is the issue and not working? I opened up the image but it did not say anything about the issue.
Yvar Birx 24-Feb-13 13:09pm
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.
Philippe Mori 24-Feb-13 22:35pm
The computation of DeltaPoint look wrong. I'm not sure of what angle you want so it somewhat hard to answer.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

Please see:
Calculating degrees fails![^].

Please don't re-post anymore.

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

I would use the scalar product formula, namely 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;
Yvar Birx 24-Feb-13 16:14pm
This returns as NaN?
CPallini 24-Feb-13 16:45pm
It shouldn't. What are your input values?
Yvar Birx 25-Feb-13 1:47am
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)));
Sergey Alexandrovich Kryukov 24-Feb-13 19:15pm
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.
CPallini 25-Feb-13 5:25am
Are you kidding?
Yvar Birx 25-Feb-13 7:02am
CPallini 25-Feb-13 7:53am
I've tested the formula with 10000 random inputs. It never produced a NaN.
Yvar Birx 25-Feb-13 9:03am
" 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.

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."
CPallini 25-Feb-13 9:28am
That's fine: Player = {0,0} is a meaningless input.
You cannot find the angle with a vector having modulus equal to zero.
Sergey Alexandrovich Kryukov 25-Feb-13 11:54am
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...

Sergey Alexandrovich Kryukov 25-Feb-13 14:11pm
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:
CPallini 27-Feb-13 3:44am
You might do a test, like I did (I've found NO appreciable difference between the two methods).
Sergey Alexandrovich Kryukov 27-Feb-13 10:59am
CPallini 27-Feb-13 12:39pm
Sergey Alexandrovich Kryukov 27-Feb-13 13:11pm
Tested I, tested, long time ago... In mathematics, the truth is established not by testing, but by the proof...
CPallini 27-Feb-13 14:51pm
Well you are wrong.
We aren't playing mathematics here, we are programming.
The same happens in physics: theory is nothing without experimental proof.

Sergey Alexandrovich Kryukov 27-Feb-13 15:02pm
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?
CPallini 27-Feb-13 15:36pm
No, I question everything you said, because it is plain wrong.
Sergey Alexandrovich Kryukov 27-Feb-13 15:43pm
Did you see my solution?
CPallini 27-Feb-13 16:11pm
Sergey Alexandrovich Kryukov 27-Feb-13 16:19pm
OK then. You are starting to behave emotionally, with no evidence or proof. Perhaps it's a time to stop it...
CPallini 27-Feb-13 16:29pm
Time to stop , definitely. That's just nonsense. Axiomatic nonsense.
Sergey Alexandrovich Kryukov 27-Feb-13 17:15pm
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?
CPallini 28-Feb-13 5:24am
Could you please show one of the mismatching outputs?
Sergey Alexandrovich Kryukov 28-Feb-13 14:12pm
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...

CPallini 28-Feb-13 15:59pm
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.
Sergey Alexandrovich Kryukov 28-Feb-13 16:09pm
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...
CPallini 28-Feb-13 16:22pm
"Algorithms should be applied to all application"
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.
Sergey Alexandrovich Kryukov 28-Feb-13 16:28pm
Well, irrelevant... Atan2 is not complication, unlike relativity.
If you want to tell me excuses, it's not interesting...
CPallini 28-Feb-13 16:48pm
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.
Sergey Alexandrovich Kryukov 28-Feb-13 16:57pm
Sure, let's stop it.
Thank you for the discussion anyway.

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

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Mobile
Web02 | 2.8.170713.1 | Last Updated 25 Feb 2013
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

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