# Given X, Y, and heading as a number of degrees, determine next point along heading.

Suppose an object is moving in some direction on a 2D plane. Its direction is given as a heading, where 0 degrees is north and 180 degrees is south.

Suppose that I know the object's coordinates are 0,0 (x,y) and that its heading is 90 degrees. To maintain the current heading I know that for each whole unit I move the object along the X-axis I need to move it 0 units along the Y-axis.

But suppose the same object's heading changes to anything else, like 98 degrees. How would I determine how many units to move in each direction to maintain the current heading, where either X or Y must move a whole unit (but not necessarily both)?

I suppose the question I am asking is similar to "how do I find another point given a point and slope", but the slope is in degrees and I can't figure out how to convert that.

Here is a function and expected output if it helps clarify:

f(x,y,d) = a,b (where a and b, when added to x and y, are the next point on the line in the direction of the heading)

f(0, 0, 0) = 0,1 (heading north, so for each 1 unit added to Y we add 0 to X)
f(0, 0, 45) = 1,1
f(0, 0, 90) = 1,0
f(0, 0, 135) = 1,-1
f(0, 0, 180) = 0,-1
f(0, 0, 225) = -1,-1
f(0, 0, 270) = -1,0

f(0, 0, 18) = a,b
f(0, 0, 200) = a,b
f(0, 0, 65) = a,b


Either x or y needs to be a whole number, but one of them can be a decimal number. For example, to move x 1 point, move y 0.345 points, or vice versa.

• Could you better clarify how the $x$ and $y$-coordinate change for non-trivial angles? For example, starting from the origin, if $a=30^o$ from the north, would you like to get $(1/\sqrt{3},1)$ or $(1,\sqrt{3})$? – Anatoly Dec 7 '17 at 10:36

The function $f$ you describe is

$f(x,y,a)=(x,y)+\begin{cases} (1,\cot (a)) & 45\leq a\leq 135 \\ (-\tan (a),-1) & 135\leq a\leq 225 \\ (-1,-\cot (a)) & 225\leq a\leq 315 \\ (\tan (a),1) & \text{else} \end{cases}$

which is well-defined despite the overlapping conditions.

• Hmm, this doesn't seem quite right. It is only accurate for the first result, f(0,0,0). I'm not sure if you're familiar with JavaScript, but I put together a tester and implemented your function f(x, y, a) here: jsfiddle.net/46Lxk3f9/2 Is there something I missed or wrote incorrectly? – jdgregson Dec 7 '17 at 4:01
• @jdgregson In JavaScript you need to convert the angle in degrees to radians. That is replace tan(a) by tan(pi*a/180) and cot(a) by cot(pi*a/180) – MeMyselfI Dec 7 '17 at 8:17
• Ah, when I implemented that all test cases passed (almost): jsfiddle.net/46Lxk3f9/3 - I say "almost" because each answer was still off, but only be a very small decimal number. When I rounded the output I got what I was looking for. I'll throw this into the program tonight and see if it solves everything. – jdgregson Dec 7 '17 at 22:04
• After converting this to JavaScript I find this answer to be the easiest to use and highly accurate. Thanks for the help! – jdgregson Dec 8 '17 at 4:51

The function can be written as $$f(x,y,d)=(x,y)+\begin{cases} (0,1)\quad &\quad d=0^\circ\\\\ (0,-1)\quad &\quad d=180^\circ\\\\ \left((-1)^{\left\lfloor\frac{d}{180}\right\rfloor},(-1)^{\left\lfloor\frac{d}{180}\right\rfloor}\cot\left(\dfrac{d\pi}{180}\right)\right)\quad &\quad\text{else}\end{cases}$$ where $\lfloor x\rfloor$ represents the greatest integer less than or equal to $x$.

You can see that this $f$ satisfies the following examples you've shown :

f(0, 0, 0) = 0,1 (heading north, so for each 1 unit added to Y we add 0 to X)

f(0, 0, 45) = 1,1
f(0, 0, 90) = 1,0
f(0, 0, 135) = 1,-1
f(0, 0, 180) = 0,-1
f(0, 0, 225) = -1,-1
f(0, 0, 270) = -1,0


and that

\begin{align}f(0, 0, 18)& = \left(1,\cot \left(\dfrac{\pi}{10}\right)\right)\approx (1,3.0776835)\\\\f(0, 0, 200) &=\left(-1,-\cot\left(\dfrac{10\pi}{9}\right)\right)\approx (-1,-2.7474774)\\\\f(0, 0,65) &=\left(1,\cot \left(\dfrac{13\pi}{36}\right)\right)\approx (1,0.4663077)\end{align}

• You assume that the integer, unit step always occurs in the $x$-axis direction, but this is not specified in the text. – Anatoly Dec 7 '17 at 13:26
• @Anatoly: OP says "How would I determine how many units to move in each direction to maintain the current heading, where either X or Y must move a whole unit (but not necessarily both)?", so I think that assumption is OK. – mathlove Dec 7 '17 at 14:58
• Right! For the sake of clarity, I just added an integration to your correct answer, to account for both possibilities. – Anatoly Dec 7 '17 at 15:02

Just to give a little integration to the correct answer by mathlove, since the OP does not specify criteria to decide, for angles that are not multiples of $\pi/4$, whether the integer unit step must be taken in the $x$- or $y$-axis direction. To follow the notation of the OP, I will express angles in degrees. Let us assume that the initial coordinates of the object are $(0,0)$. For a movement from the origin along a line that forms an angle $\theta$ with the $x$-axis (measured using the conventional approach of increasing angles in the counterclockwise direction), a unit change in the $x$-coordinate corresponds to a shift by $\tan(\theta)$ in the $y$-coordinate. In a symmetric fashion, a unit change in the $y$-coordinate corresponds to a shift by $\cot(\theta)$ in the $x$-coordinate.

These considerations must be applied to the particular definition of the angle described in the OP, where $0^o$ corresponds to the "north", i.e. $90^o$ of the standard definition, and where increasing values go in a clockwise direction. If $a$ is the angle identified using this alternative definition, we have $\theta=-a+90^o \,\,$. Now note that the new coordinates depend on whether we decide to assign the unit step to the $x$- or $y$-axis. The assignment to the $x$-axis is possible only for $a \neq 0^o$ and $a \neq 180^o$ (values for which we get the trivial results of $(0,1)$ and $(0,-1)$, respectively), whereas that to the $y$-axis is possible only for $a \neq 90^o$ and $a \neq -90^o$ (values for which we get the trivial results of $(1,0)$ and $(-1,0)\,$). Under these restrictions, if we assign the unit step to the $x$-axis, the new coordinates are given by

$$\left(1,\cot(a)\right) \,\,\, \text{if} \,\,\, 0^o<a<180^o$$ $$\left(-1,-\cot(a)\right) \,\,\, \text{if} \,\,\, 180^o<a<360^o$$

whereas if we assign the unit step to the $y$-axis they are

$$\left(\tan(a),1 \right) \,\,\, \text{if} \,\,\, -90^o<a<90^o$$ $$\left(-\tan(a), -1 \right) \,\,\, \text{if} \,\,\, 90^o<a<270^o$$

With this double option, the examples of the OP become

$$f(0, 0, 18) = \left(1,\cot ( 18^o ) \right) \,\,\, \text{or} \,\,\, \left(\tan ( 18^o ),1 \right)$$

$$f(0, 0, 200) = \left(-1,-\cot ( 200^o ) \right) \,\,\, \text{or} \,\,\, \left(-\tan ( 200^o ),-1 \right)$$

$$f(0, 0, 65) = \left(1,\cot ( 65^o ) \right) \,\,\, \text{or} \,\,\, \left(\tan ( 65^o ),1 \right)$$