<style> .reveal-up, .reveal-left, .reveal-right, .reveal-stagger > * { opacity: 1 !important; transform: none !important; } </style>
  1. Learn
  2. BIM Math
  3. Foundations
All lessons in this course

Lesson 4 of 44 14 minBeginner

Angles: degrees, radians and Atan2

Radians and why C# uses them, finding a direction’s angle correctly with Atan2, normalising angles, and converting between maths angles and compass bearings.

Drawings use degrees: a 90° corner, a 45° chamfer, a wall at 30°. C#’s Math.Sin, Math.Cos and Math.Tan use radians. Mixing them up is one of the most common geometry bugs, so it is worth understanding what a radian is.

What is a radian?

Draw a circle of radius 1. Walk around its edge a distance of 1: the angle you have turned is one radian (about 57.3°). A full circle is 2π ≈ 6.283 radians, because the circumference of a unit circle is 2π. So 360° = 2π, 180° = π and 90° = π/2.

Degrees0°30°45°90°180°270°360°
Radians0π/6π/4π/2π3π/22π
Decimal00.5240.7851.5713.1424.7126.283
Radians.cs
static double ToRadians(double deg) => deg * Math.PI / 180;static double ToDegrees(double rad) => rad * 180 / Math.PI; Console.WriteLine(Math.Sin(90));                          // the bug: 90 radiansConsole.WriteLine(Math.Sin(ToRadians(90)));               // what was meantConsole.WriteLine($"{ToDegrees(1):F4}");                  // one radian in degrees
Output
0.8939966636005579
1
57.2958

The angle of a direction: use Atan2

A wall runs from (x₁, y₁) to (x₂, y₂). What angle does it make with the X axis? The slope is dy / dx, and the tangent of the angle is that slope, so it is tempting to write Math.Atan(dy / dx). That is wrong in two ways:

  • dy / dx loses the signs: a wall going up-right (2, 2) and one going down-left (−2, −2) have the same slope, 1, so Atan gives 45° for both, though they point in opposite directions.
  • A vertical wall has dx = 0. With double coordinates the division gives ±∞, which Atan happens to survive; with int coordinates it throws a DivideByZeroException, and a zero-length wall gives NaN.

Math.Atan2(dy, dx) takes the two values separately, so it knows the quadrant and handles dx = 0. It returns an angle between −π and π. Drag the point around the dial to compare the two.

Interactive

Atan vs Atan2

Drag the green point (or focus it and use the arrow keys). The purple line is the true direction from Atan2; the red dashed line is what Atan(dy / dx) thinks.

+X 0°+Y 90°180°270°Q1Q2Q3Q4
dx, dy-3, 2
Atan(dy / dx)-33.7°
Atan2(dy, dx)146.3°
in radians2.554
normalised [0, 360)146.3°
compass bearing303.7°
dx is negative, so dy / dx = -0.67 lost the signs. Atan sees the same slope as the opposite direction and is off by 180°. Atan2 keeps dy and dx separate and gets 146.3°.
Direction.cs
// Angle of a direction, counter-clockwise from +X, in [0, 360).static double DirectionDeg(double dx, double dy){    double deg = Math.Atan2(dy, dx) * 180 / Math.PI;    return deg < 0 ? deg + 360 : deg;} Console.WriteLine($"{Math.Atan(-2.0 / -2.0) * 180 / Math.PI:0.##}");  // Atan: wrong quadrantConsole.WriteLine(DirectionDeg(-2, -2));Console.WriteLine(DirectionDeg(0, 5));Console.WriteLine(DirectionDeg(3, -3));
Output
45
225
90
315

Normalising angles

Angles wrap: 370°, 10° and −350° are the same direction. Before comparing angles or showing them, bring them into one standard range. Two ranges are common: [0, 360) for directions, and (−180, 180] for turns, where the sign tells you left (+) or right (−).

Normalise.cs
static double To360(double deg){    deg %= 360;                      // C#'s % keeps the sign: -350 % 360 = -350    return deg < 0 ? deg + 360 : deg;} static double ToPlusMinus180(double deg){    deg = To360(deg);    return deg > 180 ? deg - 360 : deg;} Console.WriteLine(To360(370));Console.WriteLine(To360(-350));Console.WriteLine(ToPlusMinus180(270));        // a 270 left turn is a 90 right turnConsole.WriteLine(ToPlusMinus180(350 - 10));   // turn from 10 to 350
Output
10
10
-90
-20

The last line is the important one: the turn from heading 10° to heading 350° is not +340°, it is 20° to the right. Taking the difference and normalising it to (−180, 180] always gives the short way round.

Maths angles vs compass bearings

Maths measures angles counter-clockwise from east (+X). Surveyors and site plans use bearings: clockwise from north (+Y). Both describe the same direction, so converting is one line: bearing = 90 − angle, normalised to [0, 360).

DirectionMaths angleBearing
East0°90°
North90°0°
West180°270°
South-west225°225°
South-east315°135°
Quick check

What does Math.Cos(60) compute?

Quick check

A wall runs from (5, 5) to (1, 5). What does Math.Atan2(dy, dx) return, in degrees?

Quick check

A path heads 350° and then turns to head 20°. What is the turn, normalised to (−180, 180]?

Practice

A run of walls goes through the points (0, 0) → (6, 0) → (6, 4) → (2, 7). At each inner corner, print how far the run turns and whether it turns left or right, to one decimal place.

Show a hint

Find each wall’s direction with Atan2, take the difference between consecutive directions, normalise it to (−180, 180], and use the sign: positive is left.

Show the solution
Solution.cs
using Pt = (double X, double Y); static double Dir(Pt a, Pt b) => Math.Atan2(b.Y - a.Y, b.X - a.X) * 180 / Math.PI; static double ToPlusMinus180(double deg){    deg %= 360;    if (deg < 0) deg += 360;    return deg > 180 ? deg - 360 : deg;} Pt[] run = { (0, 0), (6, 0), (6, 4), (2, 7) }; for (int i = 1; i < run.Length - 1; i++){    double turn = ToPlusMinus180(Dir(run[i], run[i + 1]) - Dir(run[i - 1], run[i]));    string side = turn >= 0 ? "left" : "right";    Console.WriteLine($"At {run[i]}: {side} {Math.Abs(turn):F1} deg");}
Output
At (6, 0): left 90.0 deg
At (6, 4): left 53.1 deg

Remember

  • C# trig functions use radians: 360° = 2π. Convert with deg * Math.PI / 180.
  • Find a direction’s angle with Math.Atan2(dy, dx) (Y first). Atan(dy / dx) gets the quadrant wrong and fails on vertical lines.
  • Normalise angles before comparing them: [0, 360) for directions, (−180, 180] for turns.
  • Maths angles run counter-clockwise from east; bearings run clockwise from north: bearing = 90 − angle.
0 of 44 lessons completed