Get angle between point and origin
Asked Answered
J

5

10

This might have been answered before, sorry if it has. I basically need to get the angle from origin to point. So lets say Origin is (0, 0) and my target point is (3, 0).

3 O'clock = 90 degrees

6 O'clock = 180 degrees

9 O'clock = 270 degrees

12 O'clock = 0 degrees


Somehow, I gotta do some math magic, and find out that the angle is 90 degrees (Top is 0). The origin can vary, so I need a method with two parameters, Origin, and TargetPoint, which returns double Angle in Degrees.

Yea, I realize this looks short and nonconstructive, but I made the question as simple and understandable as possible. All the other questions were closed -.-

Thanks

Judi answered 8/7, 2013 at 15:13 Comment(4)
An angle is between two lines... not two points, unless you're talking of the angle of a line compare to say, the world itself? Also... is this for a homework?Podite
No, I need the angle between origin and a point. Think of it as a clock, 3 O'clock is 90 degrees about Origin (center). No, I'm working on a game.Judi
@Podite Why do people have so much trouble understanding this question? Of COURSE you can't technically have an angle between two points, but why is it so hard to understand that a lot of programmers haven't been taught this? All they know is they 0 degrees is up and they need to find an angle that will make one sprite point at another sprite. Most programmers that ask this question simply don't have the maths background to grasp the concept of needing three points (or two lines, if you like) for an angle. [/rant]Miscall
@Clonkex; I agree. It's also shorthand. When I am looking for "the angle of a point", I suppose I could say something more explicit, like "I want to find the the angle between the x-axis representing zero degrees and the line on which two points fall, one of them being the notional origin and the other being a variable point in question", but I think it's fair to assume what is meant by the question, especially because, as a programmer, you are only given two points, not a line, to work from.Prady
C
20

The vector between two points A and B is B-A = (B.x-A.x, B.y-A.y). The angle between two vectors can be calculated with the dot product or atan2.

var vector2 = Target - Origin;
var vector1 = new Point(0, 1) // 12 o'clock == 0°, assuming that y goes from bottom to top

double angleInRadians = Math.Atan2(vector2.Y, vector2.X) - Math.Atan2(vector1.Y, vector1.X);

See also Finding Signed Angle Between Vectors

Carty answered 8/7, 2013 at 15:16 Comment(7)
So: Math.Atan2(Origin.Y - Target.Y, Origin.X - Target.X);? And this is Radians, right?Judi
@user2544245: You need two vectors. The second vector points into the direction that you want to represent 0°. Clockwise, yes. Your formula is wrong, though.Carty
In your formula, does it matter which one is Origin and which is Target?Judi
@user2544245: Your question does not make sense. You need two vectors! One of them is derived from Origin and Target, the other from the direction of your 0° vector.Carty
Also, how can I get a point from Origin using an Angle in Radians and a Length. Or.. Should I make a new question for it?Judi
@user2544245: x = Lengthcos(angle); y= Lengthsin(angle)Carty
And if my Origin is not (0, 0), then I just do: ((Length * Cos(angle)) + Origin.X, (Length * Sin(angle)) + Origin.Y)?Judi
Y
4

Assuming x is positive, something like this:

angle = Math.Atan(y / x) * 180 / Math.PI + 90

Edited to allow for negative x values:

If it can be negative, just do it by case. Something like this:

if (x < 0) {
    angle = 270 - (Math.Atan(y / -x) * 180 / Math.PI);
} else {
    angle = 90 + (Math.Atan(y / x) * 180 / Math.PI);
}
Yseulte answered 8/7, 2013 at 15:27 Comment(1)
Well X and Y can be positive or negative.Judi
M
0
public static double GetAngleDegree(Point origin, Point target) {
    var n = 270 - (Math.Atan2(origin.Y - target.Y, origin.X - target.X)) * 180 / Math.PI;
    return n % 360;
}

static void Main(string[] args)
{
    Console.WriteLine(GetAngleDegree(new Point(0, 0), new Point(0, 3)));//0
    Console.WriteLine(GetAngleDegree(new Point(0, 0), new Point(3, 0)));//90
    Console.WriteLine(GetAngleDegree(new Point(0, 0), new Point(0, -3)));//180
    Console.WriteLine(GetAngleDegree(new Point(0, 0), new Point(-3, 0)));//270 
}
Marjana answered 8/7, 2013 at 15:37 Comment(1)
This looks like it's going CounterClockwise, with (0, 3) being 0 Degrees.Judi
L
0

Actually there is no way to find out the angle between point and origin due to the fact that the origin is (0,0). We can calculate the angle between 2 points beacuse they are treated like vectors and as such they have a direction, but the origin has no direction. For that reason, if you want to find the angle using the example of a clock you can calculate the angle between the point and (1,0) for example being that point at 0 degrees.

I'm sorry I'm not versed in C# but you can have a look at this java code which is similar:

double getAngle2PointsRad(double p1_x, double p1_y, double p2_x, double p2_y) {
  return Math.acos((((p1_x * p2_x) + (p1_y * p2_y)) / (Math.sqrt(Math.pow(p1_x, 2) + Math.pow(p1_y, 2)) * Math.sqrt(Math.pow(p2_x, 2) + Math.pow(p2_y, 2)))));
}

double getAngle2PointsDeg(double p1_x, double p1_y, double p2_x, double p2_y) {
  return Math.acos((((p1_x * p2_x) + (p1_y * p2_y)) / (Math.sqrt(Math.pow(p1_x, 2) + Math.pow(p1_y, 2)) * Math.sqrt(Math.pow(p2_x, 2) + Math.pow(p2_y, 2))))) * 180 / Math.PI;
}

If you try to calculate using (0,0) you will get NaN beacuse it tries to divide by zero.

Lee answered 14/6, 2016 at 10:25 Comment(0)
G
0

For whatever its worth to anyone who might still come to this post (it was toward the top of Google for me), I used Sebastian's Atan2 for my solution and it worked quite well. In my case, I'm programmatically generating parameterized primitives in Unity, so the origin point is always (0, 0, 0), whether the primitive is 2D or 3D (for the sake of Mesh vertices). So for a sphere, I needed to order all of the vertices in a specific way so that regardless of the parameters, an int[] could be properly built for the triangles needed for the mesh.

My sorting is done using:

this.vertices = vertList.OrderByDescending(o => o.y)
                        .ThenBy(o => Utilities.GetAngle(o)).ToArray();

And the GetAngle() method looks like this:

public static float GetAngle(Vector3 v)
{
    return Mathf.Atan2(0, 0) - Mathf.Atan2(v.z, v.x);
}

It works to sort the list of vertices from top to bottom (so a 1 unit sphere would have a "top" point at (0f, 0.5f, 0f), and that would be the first vertex), and then ordered by the resulting float from the angular calculation along the X- and Z-planes. This sorting works wonderfully and surprisingly quickly for Linq.

One additional note: because it ignores the Y-plane, it doesn't matter that each layer/level/band of vertices is at different points on the Y - it basically calculates each as if they were just at y = 0. If you were trying to sort across X/Y or Y/Z, you could do the same thing just omitting the plane you want to ignore.

This would likely not work in more complex situations, or where your origin is not (0, 0, 0), but worked at least for my case.

Gustafsson answered 16/9, 2021 at 17:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.