Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#
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
Edited 24-Feb-13 4:23am
v2
Comments
Sandeep Mewara at 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 at 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 at 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
good
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;
  }
  Permalink  
Comments
Yvar Birx at 24-Feb-13 16:14pm
   
This returns as NaN?
CPallini at 24-Feb-13 16:45pm
   
It shouldn't. What are your input values?
Yvar Birx at 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 at 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.
—SA
CPallini at 25-Feb-13 5:25am
   
Are you kidding?
Yvar Birx at 25-Feb-13 7:02am
   
?
CPallini at 25-Feb-13 7:53am
   
I've tested the formula with 10000 random inputs. It never produced a NaN.
Yvar Birx at 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.
 
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."
CPallini at 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 at 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...
 
—SA
Sergey Alexandrovich Kryukov at 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:
http://www.codeproject.com/Answers/552477/Calculatingplusdegreesplusfails#answer2.
—SA
CPallini at 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 at 27-Feb-13 10:59am
   
(Sigh...)
CPallini at 27-Feb-13 12:39pm
   
?!
Sergey Alexandrovich Kryukov at 27-Feb-13 13:11pm
   
Tested I, tested, long time ago... In mathematics, the truth is established not by testing, but by the proof...
—SA
CPallini at 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 at 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?
—SA
CPallini at 27-Feb-13 15:36pm
   
No, I question everything you said, because it is plain wrong.
Sergey Alexandrovich Kryukov at 27-Feb-13 15:43pm
   
Did you see my solution?
—SA
CPallini at 27-Feb-13 16:11pm
   
Yes.
Sergey Alexandrovich Kryukov at 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...
—SA
CPallini at 27-Feb-13 16:29pm
   
Time to stop , definitely. That's just nonsense. Axiomatic nonsense.
Sergey Alexandrovich Kryukov at 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?
—SA
CPallini at 28-Feb-13 5:24am
   
Could you please show one of the mismatching outputs?
Sergey Alexandrovich Kryukov at 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...
 
—SA
CPallini at 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 at 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...
—SA
CPallini at 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 at 28-Feb-13 16:28pm
   
Well, irrelevant... Atan2 is not complication, unlike relativity.
If you want to tell me excuses, it's not interesting...
—SA
CPallini at 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 at 28-Feb-13 16:57pm
   
Sure, let's stop it.
Thank you for the discussion anyway.
:-)
—SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Please see:
Calculating degrees fails![^].
 
Please don't re-post anymore.
 
—SA
  Permalink  

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

  Print Answers RSS
0 Maciej Los 404
1 OriginalGriff 379
2 CPallini 145
3 Sergey Alexandrovich Kryukov 142
4 Hard_Rockz 115
0 OriginalGriff 5,634
1 Sergey Alexandrovich Kryukov 4,763
2 Peter Leow 2,954
3 Maciej Los 2,614
4 DamithSL 2,465


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