Solution using Modulo

A simple solution that catches all cases.

degrees = (degrees + 360) % 360;  // +360 for implementations where mod returns negative numbers

Explanation

Positive: 1 to 180

If you mod any positive number between 1 and 180 by 360, you will get the exact same number you put in. Mod here just ensures these positive numbers are returned as the same value.

Negative: -180 to -1

Using mod here will return values in the range of 180 and 359 degrees.

Special cases: 0 and 360

Using mod means that 0 is returned, making this a safe 0-359 degrees solution.

Answer from Liam George Betsworth on Stack Overflow
Discussions

math - Convert atan2 value to standard 360-degree-system value - Stack Overflow
This gives me a value between 0 and 180 degrees or between 0 and -180 (the nature of atan2). Is there a way to convert the value received with this function (after it's been converted to degrees), to the standard 360-degree-system, without changing the angle - only the way it's written? More on stackoverflow.com
🌐 stackoverflow.com
mathematics - How does atan2 work when getting angle of a vector? - Game Development Stack Exchange
I know that atan2 gives me the absolute angle of any vector. But it doesn't give a value from 0 to 360 degrees. Instead, it gives a value (if I'm not mistaken), between 0 and 180, or between 0 and ... More on gamedev.stackexchange.com
🌐 gamedev.stackexchange.com
February 1, 2014
Highest scored 'atan2' questions - Stack Overflow
I have U and V wind component data ... in R. I would like to end up with wind direction data on a scale of 0-360 degrees, with 0° or 360° ... ... I am calculating angles from a 3-axis accelerometer, but my compiler doesn't have a atan or atan2 function.... More on stackoverflow.com
🌐 stackoverflow.com
How to achieve 360 degree display using arctangent by case structure?
I have sine and cosine signals. The tangent and arctangent are used to get the -90 to 90 degree. To achieve the 360 degree display, I will use the absolute value and additional degree, such as 90 180 and 270. I have created the case and select parts, but I don't know how to link this two. More on forums.ni.com
🌐 forums.ni.com
1
0
July 17, 2009
🌐
PHP
php.net › manual › en › function.atan2.php
PHP: atan2 - Manual
* | | | | * | | | | * | +-----[ -y]-----+ | * {-135}-------{-90}-------{-45} * * * SO, we simply transpose the (y,x) parameters to atan2(x,y) * which will both rotate(left) and reflect(mirror) the compass.
🌐
Dirask
dirask.com › posts › Python-math-atan2-method-example-D6MBZ1
Python - math.atan2() method example
import math def calculate_angle(x, y): angle = math.atan2(x, y) if angle < 0: angle += 2 * math.pi return (180 / math.pi) * angle # y x degrees print(calculate_angle(2, 4)) # 26.56505117707799 print(calculate_angle(4, -2)) # 116.56505117707799 print(calculate_angle(-2, -4)) # 206.565051177078 print(calculate_angle(-4, 2)) # 296.565051177078 · This section shows how to convert angles to counterclockwise angles (from -360 to 0 degrees).
🌐
Steam Community
steamcommunity.com › app › 573090 › discussions › 0 › 3275815819066451629
Finding the angle of an object (0 - 360 degrees) :: Stormworks: Build and Rescue General Discussions
((1-x)%1)*360 Converts the compass -0.5 to 0.5 into 0-360 degree angle. atan2 also returns radians from 0 to 2pi, so you might have something mixed up when you state it returns 0-360 degrees.
Find elsewhere
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › Math › atan2
Math.atan2() - JavaScript - MDN Web Docs
December 29, 2025 - The Math.atan2() method measures the counterclockwise angle θ, in radians, between the positive x-axis and the point (x, y). Note that the arguments to this function pass the y-coordinate first and the x-coordinate second. Math.atan2() is passed separate x and y arguments, while Math.atan() is passed the ratio of those two arguments. Math.atan2(y, x) differs from Math.atan(y / x) in the following cases: In addition, for points in the second and third quadrants (x < 0), Math.atan2() would output an angle less than
🌐
MathWorks
mathworks.com › matlabcentral › fileexchange › 39369-atan2-0-360
atan2(0..360) - File Exchange - MATLAB Central
December 10, 2012 - Function calculates the arc tangent of y/x and places the result in range of [0..360]. To find similar examples and resources please visit www.smallsats.org · Small Satellites (2025). atan2(0..360) (https://www.mathworks.com/matlabcentral/...
🌐
Stack Overflow
stackoverflow.com › questions › tagged › atan2
Highest scored 'atan2' questions - Stack Overflow
Lets say I'm using atan2 to get the angle between two vectors. atan2 gives a value in radians. I convert it to degrees using a built in function in Java. This gives me a value between 0 and 180 ... ... Math has defeated me once again. This is such a simple task, but I can't manage to get it done.
🌐
Unity
discussions.unity.com › questions & answers
How to get 0-360 degree from two points - Questions & Answers - Unity Discussions
August 20, 2015 - Is there a function that will return degrees (0-360) from one point (x = 0, z = 0) to another point (-x = 3, -z = 5) Edited to add exact code snippet that worked for me. GameObject target = GameObject.Find("Name Of Game Object In Hierarchy"); float MyPositionX = transform.position.x; float MyPositionZ = transform.position.z; float TargetPositionX = target.transform.position.x; float TargetPositionZ = target.transform.position.z; degree = FindDegree(MyPositionX - TargetPositionX, MyPositi...
Top answer
1 of 1
10

atan2 is a mathematical function; it is stateless. There is nothing in it to “know” that you want an angle which is close to the angle from the previous frame, as opposed to an angle which is simply sufficient to identify the direction.

You must write your own logic to handle this case. There are several possible behaviors you could implement; here's the ones I've thought of. Note that I am not familiar with C#, XNA, or Farseer, so I have only pseudocode here, but all of these should work as long as you can retrieve the joint's current actual angle as well as the target angle.

  1. The joint should spin the smallest amount to match the direction of the joystick. This means that if the user spins the stick faster than the joint can keep up, it will start turning the other direction to make a shorter motion. This can be implemented as:

    let currentStickDirection = atan2(RightStick.Y, RightStick.X)
    let currentJointDirection = currentJointAngle mod 2π
    let difference = ((currentStickDirection - currentJointDirection + π) mod 2π) - π
    jointTargetAngle = currentJointAngle + difference
    

    The addition and subtraction of π (a half-turn) combined with modulus puts the difference-between-angles in the range −π…+π, which is the “smallest amount to match” property.

    Note that if you are implementing, for example, a turret, then this might be undesirable as it makes it harder to strafe a particular arc as the player needs to make sure not to lead too much.

  2. The joint should follow the motions of the stick. That is, if the user quickly makes multiple revolutions of the stick, the joint will follow and make multiple revolutions even if the user's movement is long over.

    To implement this, the logic is the same as above except that instead of using the joint's current actual angle, we use the joint's target angle (which can be simply a variable/field in your program, unrelated to the physics engine) as the state input.

    let currentStickDirection = atan2(RightStick.Y, RightStick.X)
    let currentJointDirection = jointTargetAngle mod 2π
    let difference = ((currentStickDirection - currentJointDirection + π) mod 2π) - π
    jointTargetAngle += difference
    
  3. Same as option 2, but the joint will never make an unnecessary full revolution. This differs from option 1 in that the joint will always turn in the same direction as the input does.

    To implement this, use the code from option 2, but after all of the above we also remove extra ±2πs from the target angle:

     let revolutions = (jointTargetAngle - currentJointAngle) / 2π
     if (revolutions >= 1)
         jointTargetAngle -= floor(revolutions) * 2π
     else if (revolutions <= -1)
         jointTargetAngle -= ceil(revolutions) * 2π
    

Note that if the stick is near its center, then small motions, possibly including noise/vibration rather than user motion, will cause large changes in the computed angle. If you haven't already, you will probably want to add a “dead zone” around the center which disables the angle computation. This can be a simple distance condition, like pow(RightStick.Y, 2) + pow(RightStick.X, 2) < pow(deadZoneRadius, 2).

Another interesting option would be to reduce the “motor power” of the joint (I don't know what exact options Farseer provides in this area) depending on the computed distance, so that small pushes on the stick can be used to slowly swing the joint (note that then the imprecision of direction matters less) and moving it to the limit does a fast swing. This would naturally reduce the effect of noise about the center, but unless you are using option 1 above (which does not depend on the previous target angle) and your joystick has perfect mechanical return-to-center, you will still want to have a deadzone.


Commentary: The two key principles here are:

  1. Work with differences between angles, not absolute angles.
  2. Make sure that (where appropriate for the application) you are treating any particular angle θ as equivalent to θ + 2π. This is the reason for all of the uses of modulo; the π offsets are used to control where we flip from positive to negative numbers, which affects the overall behavior of the algorithm, but not in a way which is dependent on the input range.
🌐
Bohemia Interactive Community
community.bistudio.com › wiki › atan2
atan2 - Bohemia Interactive Community
March 25, 2024 - _yx = _obj1 worldToModel getPosASL _obj2; _dir = (_yx select 0) atan2 (_yx select 1); // _dir range from -180 to +180 _dir = (_dir + 360) % 360; // _dir range from 0 to 360 · See also: atan tan sin cos asin acos rad pi vectorCos BIS_fnc_dirTo getRelPos getRelDir ·
🌐
Reddit
reddit.com › r/unity2d › how to get 0-360 bearing in 2d?
r/Unity2D on Reddit: How to get 0-360 bearing in 2D?
October 24, 2020 -

Hi everyone,

in my top-down 2D project I have a submarine that can rotate and move around the map. I would like to find the bearing to another 2D object, such as a ship. The 0 bearing is to the front of the submarine (its bow, or "nose"), the 90 bearing is to its right, 270 is to its left, and 180 is directly behind it, like this:

However, whenever the submarine turns, the code should reflect this, and update the bearing, and return a number like this:

The code I pasted below sort of works: it returns a bearing that is close to what it should be, BUT only when the player submarine is stationary. As soon as it starts to move, the values do not change as they should. Also, it's intended for 3D.

float angle = Quaternion.FromToRotation(Vector3.right, target.position - player.position).eulerAngles.z;

I've also found this code at this link (https://answers.unity.com/questions/434657/given-starting-transform-and-target-position-how-t.html), which I've been unable to adapt to 2D so far. I'm not sure how to refactor it.

// Takes a starting object's Transform, and a target object's position, and returns the angle to the target 0-359°

public float GetBearing(Transform startTransform, Vector3 targetPosition) {

Vector3 vectorToTarget = targetPosition - startTransform.position;

float angleToTarget = Vector3.Angle(startTransform.right, vectorToTarget);

int direction = AngleDir(startTransform.right, vectorToTarget, startTransform.up);

return (direction == 1) ? 360f - angleToTarget : angleToTarget;

return angleToTarget;

}

int AngleDir(Vector3 forwardVector, Vector3 targetDirection, Vector3 upVector) {

float direction = Vector3.Dot(Vector3.Cross(forwardVector, targetDirection), upVector);

if (direction > 0f) {

return 1;

} else if (direction < 0f) {

return -1;

} else {

return 0;

}

}

I'd appreciate any ideas.

🌐
Dankelley
dankelley.github.io › oce › reference › angleRemap.html
Convert Angle From 0:360 to -180:180 Convention — angleRemap • oce
The method is to use the cosine and sine of the angle in order to find "x" and "y" values on a unit circle, and then to use atan2() to infer the angles. ... A vector of angles, in the range -180 to 180. ... library(oce) # fake some heading data that lie near due-north (0 degrees) n <- 20 heading ...