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 时突然反转转向方向。

我需要找到一种更有效的方法来获得以度为单位的转弯量(我不能简单地设置headingtargetHeading,因为在最大转弯量中有一些模拟),以便它检测到从当前航向击中 350* 航向10*,继续减去航向。

抱歉,解释太长了。

[编辑]:潜在的解决方案 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 回答