-1

I'm developing a model for the collision for two ships.

First, I have the angle that the first ship would be pointing if it was to directly point at the second ship. I'll call the angle between the two ships $\phi$.

Next, I have the measured angle of the first ship's trajectory, which I'll call $\theta$.

The problem is, I check if $\theta$ is greater or less than $45^{\circ}$ from $\phi$. This is fine if the $\phi$ is, say, $180^{\circ}$, and $\theta$ is, say, $170^{\circ}$. This is fine until I hit the problem of $0^{\circ}$. If $\phi$ is $10^{\circ}$, and $\theta$ is $357^{\circ}$, it would still be within that $45^{\circ}$ radius. However, it would not be detected.

What is an easy/simple way to solve it so that if $\phi = 10^{\circ}$ and $ \theta = 357^{\circ}$ would still be detected as within the $45^{\circ}$ radius?

2 Answers2

1

If your angles are within $[0,360]$, the cyclic distance is given by $$d_\text{cyc}(\alpha_1,\alpha_2) = \min (|\alpha_1 - \alpha_2|, 360^\circ - |\alpha_1 - \alpha_2|)$$ You want to check if $d_\text{cyc}(\alpha_1, \alpha) \le 45^\circ$.

Here's a step-by-step evaluation of $d_\text{cyc}(10,357)$:

$$\min(|10-357|,||10-357|-360|) = \min(|-347|,360 - |-347|) = \min(347, 360-347) = \min(347,13) = 13$$

AlexR
  • 24,905
  • What is "min"? Ans what is dcyc? Also, why is checking if dcyc is less than 45 at all helpful? Am I going to have to do two separate checks with both 45 and 405? – user2722083 Mar 28 '15 at 22:32
  • @user2722083 $d_\text{cyc}$ is precisely the angle you want to compute, $\min$ is the minimum (smallest of the two values) and $|\cdot|$ is the absolute value. – AlexR Mar 28 '15 at 22:34
  • Where is |⋅|? And what are all these flat | lines for anyway? And why is there a , in the middle of it randomly? And why does checking if dcyc is less than 45 even going to remotely help me here? I seem to have so many things I'm getting confused about. – user2722083 Mar 28 '15 at 23:09
  • @user2722083 Really? I just explained every single symbol in the comment before. $d_\text{cyc}(10^\circ, 357^\circ) = 13^\circ$, for example. – AlexR Mar 28 '15 at 23:38
  • But... You haven't. I've got absolutely no idea what ANY of the min(|α1−α2|,||α1−α2|−360∘|) is talking about. I don't know why there is all the lines, I don't know why there are brackets, and I don't know about the commas. I could easily say "It does what I want, let's just implement it" and not even know why it works. Do you really want people to continue in ignorance? – user2722083 Mar 28 '15 at 23:51
  • @user2722083 Are you trolling right now? min(1,42)=1 because 1<42. |-3| = 3. – AlexR Mar 28 '15 at 23:53
  • @user2722083 I've added a complete rundown of a sample evaluation. If you still don't get it, I'm sorry for you. – AlexR Mar 28 '15 at 23:58
  • Sorry. I'm trying to work out that the |'s do. According to Wikipedia, they are the same as brackets. In fact, Wikipedia even specifically calls them brackets. – user2722083 Mar 29 '15 at 00:01
  • 1
    @user2722083 They are the absolute value. The result of $|x|$ is $x$ if $x\ge 0$ and $-x$ if $x<0$, so they "make it positive". – AlexR Mar 29 '15 at 00:04
  • Oh sh*t, I've been an absolute idiot. I understand it now. Thank you. – user2722083 Mar 29 '15 at 00:05
  • Sorry to be stupid again, I've nearly got it - I just want to ask, you said that min is the smallest of the two values. So does that mean min(15, 10) = 10, min(134, 140) = 134? – user2722083 Mar 29 '15 at 11:16
  • @user2722083 Yep, that's true. – AlexR Mar 29 '15 at 11:18
  • So this code is correct? double diff = min(abs(clrot - angle2), abs(abs(clrot - angle2) - 360)); if (diff < 45){ – user2722083 Mar 29 '15 at 12:17
  • @user2722083 Probably yes (that is if your angles are clrot and angle2 respectively). I just noticed that you can save one abs: diff = min(abs(clrot-angle2), 360 - abs(clrot-angle2)) because abs(clrot-angle2) will always be at most $360$ so $||\alpha_1 - \alpha_2| - 360| = 360 - |\alpha_1 -\alpha_2|$. – AlexR Mar 29 '15 at 12:19
  • clrot is the rotation of the client (between 0 and 360), angle2 is the angle clrot would have to be pointing at for it to point directly to the other ship. – user2722083 Mar 29 '15 at 12:24
  • @user2722083 Then it's all fine. – AlexR Mar 29 '15 at 12:24
  • Great!! My code is successfully working now. Thank you so much for putting up with my noobiness. – user2722083 Mar 29 '15 at 12:28
1

A solution to the problem would be to calculate all angles modulo $360$. That is, instead of working with the angles itself you always reduce them to their remainder when dividing by $360$. For instance, $$357 \equiv -3 \,(\mathrm{mod}\, 360)$$ In C or C++, for example, this action is done by the % operator (assuming this is for a programming context).

Edit: The "three line equal sign" is just a symbol saying "is equivalent to". You don't need to worry about that though. What the modulo operation does is very simple (as long as you know integer division!).

For example, the hours of the day are calculated modulo 24. Otherwise, we'd say that we're (roughly) at hour 17,550,000 C.E. so instead, after every 24 hour time period we start counting over again (as far as hours go).

Mathematically, this means doing integer division, but discarding everything except the remainder.

Having said this, what you actually need is more complicated (just a bit), because in most (programming) languages, $357$ modulo $360$ is still $357$. What you actually need is not just the remainder, but the smallest possible remainder in absolute value. Essentially, this is AlexR's function. Also, modulo only works for integers, so all in all my solution is quite limited. I hope you gained some understanding anyway.

GPerez
  • 6,766
  • I'm slightly confused. What's the triple-line equal sign you used, and why are you using -3? – user2722083 Mar 28 '15 at 18:55
  • Yeah, I'm really confused here. I feel like an idiot. What am I making modulo 360, and how do I do it? And where to I use it? And.. Sighs i just feel like I'm a complete noob right now. – user2722083 Mar 28 '15 at 18:59
  • @user2722083 For a programming context you can use min(abs(angle1-ang), abs(abs(angle1-min)-360)) as noted in my answer. – AlexR Mar 28 '15 at 19:04