Calculate degrees of angle using x, y coordinates
Asked Answered
M

1

5

My goal is to calculate the drag of a users finger around a center point of a scren and I've tried a few bad attempts using Math.Atan2(). FYI I am using SkiaSharp in Xamarin applications but to keep things simple I just need help with the below scenario.

Using the below screenshot could someone tell me the best way to produce the below results?

A = 0 degrees

B = 90 degrees

C = 180 degrees

D = 270 degrees

enter image description here

Miliary answered 20/1, 2019 at 19:20 Comment(2)
Why was I given negative marks, would you prefer that I show some code for a misleading not working code using Math.Atan2(yPosition, xPosition)?Miliary
Personally, I think just mentioning you tried using atan2 is enough to "show what you tried"Fluvial
E
10

Showing us the code returning the wrong result would reveal us where the problem is and allow us to give you more specific advice.

  1. Since you want the angle relative to the center, you must subtract the center coordinates from your points.

  2. Math.Atan2 yields radians. Convert them to degrees with degrees = radians * 180 / pi.

  3. Your zero angle is not as usual on the x-axis, but on the y-axis. Add 90 degrees to make the correction.

Using a vector type makes things easier. Here I will be using the System.Numerics.Vector2 struct.

As Patrick McDonald pointed out, Atan2 might yield negative results in some cases. By adding 450 degrees (360 + our 90 degrees correction) to the result and taking this modulo 360 degrees, you always get a value between 0 and 360.

public static float GetAngle(Vector2 point, Vector2 center)
{
    Vector2 relPoint = point - center;
    return (ToDegrees(MathF.Atan2(relPoint.Y, relPoint.X)) + 450f) % 360f;
}

public static float ToDegrees(float radians) => radians * 180f / MathF.PI;

The test

var a = new Vector2(7, 3);
var b = new Vector2(20, 7);
var c = new Vector2(7, 10);
var d = new Vector2(3, 7);
var e = new Vector2(6.9f, 3); // Test for more than 270 deg.
var f = new Vector2(7.1f, 3); // Test for small angle.

var center = new Vector2(7, 7);

PrintAngle(a); // ==>   0
PrintAngle(b); // ==>  90
PrintAngle(c); // ==> 180
PrintAngle(d); // ==> 270
PrintAngle(e); // ==> 358.5679
PrintAngle(f); // ==>   1.432098


void PrintAngle(Vector2 point)
{
    Console.WriteLine(GetAngle(point, center));
}
Economics answered 20/1, 2019 at 19:41 Comment(1)
💡Thats it, what I had the most trouble understanding was how you captured degrees but degrees = radians * 180 / pi makes perfect sense because a circle of 360 degrees is the same as twoπ radiansMiliary

© 2022 - 2024 — McMap. All rights reserved.