Как “привязать” направленный (2D) вектор к компасу (N, Небраска, E, SE, S, SW, W, NW)?

Вы не определили платформу, которую Вы используете, таким образом, я предполагаю, что это - Mac;-)

то, Что я делаю, использовать прокси. Я использую SquidMan, автономное внедрение Сквид

, я запускаю SquidMan на Mac, затем на iPhone I вводят параметрические усилители Прокси в Общие Настройки / Настройки Wi-Fi.

Тогда я могу следить за торговлей HTTP Консольным Приложением, смотря на squid-access.log

, Если мне нужно больше infos, я переключаюсь на tcpdump, но я предполагаю, что WireShark должен работать также.

6
задан Daren Thomas 17 September 2009 в 12:52
поделиться

4 ответа

Это работает в Java, вычисляя значение 0 ... 7 для восьми направлений:

import static java.lang.Math.*;    

int compass = (((int) round(atan2(y, x) / (2 * PI / 8))) + 8) % 8;

Результат отображается на компас следующим образом:

0 => E
1 => NE
2 => N
3 => NW
4 => W
5 => SW
6 => S
7 => SE
8
ответ дан 8 December 2019 в 05:56
поделиться

Я бы, вероятно, просто позвонил в atan2 () , чтобы определить угол курса ("рыскание"), а затем использовал бы последовательность , если : s или немного математики, чтобы «привязать» его к кратному 90 градусам.

6
ответ дан 8 December 2019 в 05:56
поделиться

Этот не использует atan2, а в худшем случае выполняет 4 сравнения и 2 продукта за один вызов. Сравнивая x с y в 4 внутренних блоках (я редактировал его только в первом блоке), можно уменьшить ровно до 4 сравнений и 1 продукт на вызов.

int compass(double x,double y)
{
  double t = 0.392699082; // tan(M_PI/8.0);

  if (x>=0)
  {
    if (y>=0)
    {
      if (x>y) { if (y<t*x) return E_COMPASS; }
      else { if (x<t*y) return N_COMPASS; }
      return NE_COMPASS;
    }
    else
    {
      if (-y<t*x) return E_COMPASS;
      if (x<-t*y) return S_COMPASS;
      return SE_COMPASS;
    }
  }
  else
  {
    if (y>=0)
    {
      if (y<-t*x) return W_COMPASS;
      if (-x<t*y) return N_COMPASS;
      return NW_COMPASS;
    }
    else
    {
      if (-y<-t*x) return W_COMPASS;
      if (-x<-t*y) return S_COMPASS;
      return SW_COMPASS;
    }
  }
  return E_COMPASS;
}
4
ответ дан 8 December 2019 в 05:56
поделиться

нет необходимости выполнять функцию atan.

если вы сделаете: y / x, вы получите наклон линии. По полученному числу можно определить угол / октант.

для положительных значений x (x> 0)

  • (y / x)> 2,4 - => 90 градусов (север)
  • 2,4> (y / x)> 0,4 ​​- => 45 градусов (северо-запад)
  • 0,4> (y / x)> -0,4 - => 0 градусов (запад)
  • -0,4> (y / x)> -2,4 - = > -45 градусов (юго-запад)
  • -2,4> (y / x) - => 90 градусов (юг)

и аналогичный список для отрицательных x

и, наконец, исключительных случаев:

  • ( x == 0 && y> 0) - => -90 градусов (юг)
  • (x == 0 && y <0) - => 90 градусов (юг)

дополнение: я сообщаю об этом методе только тогда, когда вычисление атана a no go (например, на встроенной системе))

Мне пришлось немного покопаться. Вот хорошо оптимизированная процедура, которую я использую (используется в мобильных играх).

input: x1, y1 = startpoint of vector x2, y2 = конечная точка вектора output (0-7) = 0 = север, 1 = северо-запад, 2 = запад, ... и т. д.

 int CalcDir( int x1, int y1, int x2, int y2 )
 {
      int dx = x2 - x1, dy = y2 - y1;
      int adx = (dx<0)?-dx:dx, ady = (dy<0)?-dy:dy, r;
      r=(dy>0?4:0)+(dx>0?2:0)+(adx>ady?1:0);
      r=(int []){2,3,1,0,5,4,6,7}[r];
      return r;
 }

 void CalcDirTest(){
      int t = CalcDir(0, 0, 10, 1);
      printf("t = %d",t);
      t = CalcDir(0, 0, 9, 10);
      printf("t = %d",t);
      t = CalcDir(0, 0, -1, 10);
      printf("t = %d",t);
      t = CalcDir(0, 0, -10, 9);
      printf("t = %d",t);
      t = CalcDir(0, 0, -10, -1);
      printf("t = %d",t);
      t = CalcDir(0, 0, -9, -10);
      printf("t = %d",t);
      t = CalcDir(0, 0, 1, -10);
      printf("t = %d",t);
      t = CalcDir(0, 0, 10, -9);
      printf("t = %d",t);
 }

Это приведет к следующему выводу:

 t = 7
 t = 6
 t = 5
 t = 4
 t = 3
 t = 2
 t = 1
 t = 0

(Векторы для теста могут выглядеть странно выбранными, но я немного подправили их все, чтобы они четко отображались в одном октанте, а не на точной границе)

4
ответ дан 8 December 2019 в 05:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: