0
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ 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})$? $\endgroup$ – Anatoly Dec 7 '17 at 10:36
1
+50
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – jdgregson Dec 7 '17 at 4:01
  • $\begingroup$ @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) $\endgroup$ – MeMyselfI Dec 7 '17 at 8:17
  • $\begingroup$ 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. $\endgroup$ – jdgregson Dec 7 '17 at 22:04
  • $\begingroup$ After converting this to JavaScript I find this answer to be the easiest to use and highly accurate. Thanks for the help! $\endgroup$ – jdgregson Dec 8 '17 at 4:51
0
$\begingroup$

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}$$

$\endgroup$
  • $\begingroup$ You assume that the integer, unit step always occurs in the $x$-axis direction, but this is not specified in the text. $\endgroup$ – Anatoly Dec 7 '17 at 13:26
  • $\begingroup$ @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. $\endgroup$ – mathlove Dec 7 '17 at 14:58
  • $\begingroup$ Right! For the sake of clarity, I just added an integration to your correct answer, to account for both possibilities. $\endgroup$ – Anatoly Dec 7 '17 at 15:02
0
$\begingroup$

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) $$

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.