Which Way Did the Weather Vane Turn?

complex numbers · phase · angle difference · normalising angles · pairs of neighbours

A weather station logs the wind once an hour as a complex number: the arrow points the way the wind blows, and its length is the wind speed (the speed does not matter here). The vane on the roof always turns the shorter way from one reading to the next. For every hour, the log should show how far it turned:

  • the angle, in radians, that turns the direction of reading k into the direction of reading k + 1,
  • positive for an anticlockwise turn, negative for a clockwise one,
  • always in the range -\pi < angle \le \pi: exactly half a turn, when the two arrows point in opposite directions, is written as +\pi.

The direction (the phase) of a complex number is cmath.phase(z), which lies in (-\pi, \pi]; the difference of two such phases can lie anywhere between -2\pi and 2\pi, and adding or subtracting 2\pi does not change the direction it describes. Later in this path, this same quantity will be called the relative phase of two amplitudes.

Write vane_turns(zs) that returns the list of the len(zs) - 1 turning angles, in order. It is empty when zs has fewer than two readings.

Examples

Input:  zs = [2, 1+1j, 5j, 3]
Output: [0.7853981633974483, 0.7853981633974483, -1.5707963267948966]
Explanation: east to north-east is pi/4 anticlockwise, north-east to north another pi/4,
north back to east is a quarter turn clockwise, -pi/2.

Input:  zs = [1j, -1j, -1+1j, 1-1j]
Output: [3.141592653589793, -2.356194490192345, 3.141592653589793]
Explanation: north to south is half a turn, written as +pi. From south (-pi/2) to north-west (3pi/4)
the difference of phases is 5pi/4, which is 3pi/4 = 2.356... clockwise.

Constraints

  • no reading is 0
  • whenever two neighbours do not point in exactly opposite directions, their turn is at least 1e-6 away from half a turn
  • answers are compared with a tolerance of 1e-6; do not round

Goals

  • Find the signed angle that turns one complex number's direction into another's
  • Normalise an angle into the half-open range (-pi, pi]
  • Settle the tie at exactly half a turn by the stated convention
Starting Python…