转向目标标题的方向

时间:2012-10-13 03:01:11

标签: c# compass-geolocation heading bearing

我正在使用我在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时突然反转转向。

我需要找到一种更有效的获取转弯量的方法(我不能简单地将heading设置为targetHeading,因为最大转弯量有一些模拟)所以它检测到从当前标题10 *击中350 *的航向,继续减去航向。

很抱歉很长的解释。

[编辑]:潜力解决方案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;
}

1 个答案:

答案 0 :(得分: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;
}