1

2Dマップで航空機をシミュレートするプログラムを使用しています。ターゲットベアリングに当たるために曲がる方向を見つけるのに少し苦労しています。

  double maxHeadingChange = 10; //Maximum heading change per 100 ms
  double targetHeading = 0;
  double differenceHeading = Math.Abs(targetHeading - heading);
  //if we need to turn clockwise

  if (targetHeading > 340 || targetHeading < 30)
  {
      if (heading < 180)
      {
          if (differenceHeading > maxHeadingChange)
              heading -= maxHeadingChange;
          else
              heading -= differenceHeading;
      }
      else
      {
          if (differenceHeading > maxHeadingChange)
              heading -= maxHeadingChange;
          else
              heading -= differenceHeading;
      }
  }
  else if (targetHeading > heading)
  {
      if (targetHeading - heading < maxHeadingChange)
          heading = targetHeading;
      else
          heading += maxHeadingChange;
  }
  else
  {
      if (heading - targetHeading < maxHeadingChange)
          heading = targetHeading;
      else
          heading -= maxHeadingChange;
  }

  //MessageBox.Show(headingDifference + "");
  //just for now
  //heading = targetHeading;

  if(heading > 359)
      heading = 0;
  if(heading < 0)
      heading += 360;

私がやろうとしていることは、方向を変えることです。そして、回転量が最大回転量よりも大きい場合は、最大回転量だけ回転します。

問題は、オブジェクトの方位が約10度で、ターゲットがたとえば354度の場合、時計回りに回転してそのターゲットに当たる必要があることです。これは、より小さなターゲットの方位に当たるには方位を差し引くことになるためです。 。問題は、ターゲットの方位が0を通過し、より高い方位範囲に移動するとすぐに、時計回りに回転が逆になることです。これにより、オブジェクトはその方​​向(反時計回りに回転している、または度が減少している)に向かって回転し、0を通過するとすぐに回転方向を突然逆にします。

現在の見出しから350*の見出しに当たることを検出するために、回転量を度単位で取得するより効率的な方法を見つける必要があります(最大回転量にシミュレーションがあるため、単純に設定headingすることはできません)。 targetHeading10 *の場合、見出しを減算し続けます。

長い説明でごめんなさい。

[編集]:潜在的な解決策1

  double maxHeadingChange = 10; //Maximum heading change per 100 ms
  double targetHeading = 0;
  double differenceHeading = Math.Abs(targetHeading - heading);
  //if we need to turn clockwise
  if(getTurnDir(heading, targetHeading))
  {
      //Turn right
      if(differenceHeading > maxHeadingChange)
          heading -= maxHeadingChange;
      else
          heading -= differenceHeading;
  }
  else
  {
      if (differenceHeading > maxHeadingChange)
          heading += maxHeadingChange;
      else
          heading += differenceHeading;
  }

  //MessageBox.Show(headingDifference + "");
  //just for now
  //heading = targetHeading;

  if(heading > 359)
      heading = 0;
  if(heading < 0)
      heading += 360;

double hdgDiff(double h1, double h2)
{ // angle between two headings
   double diff = h1 - h2 + 3600 % 360;
   return diff <= 180 ? diff : 360 - diff;
}
bool getTurnDir(double hdg, double newHdg)
{ // should a new heading turn left or right?
    if (newHdg > hdg)
        return newHdg - hdg > 180;
    return hdg - newHdg > 180;
}
4

1 に答える 1

5
double hdgDiff (double h1, double h2) { // angle between two headings
   const double diff = fmod(h1 - h2 + 3600, 360);
   return diff <= 180 ? diff : 360 - diff;
}

bool isTurnCCW(double hdg, double newHdg) { // should a new heading turn left ie. CCW?
   const double diff = newHdg - hdg;        // CCW = counter-clockwise ie. left
   return diff > 0 ? diff > 180 : diff >= -180;
}
于 2012-10-13T03:15:48.607 に答える