我正在使用一个程序,在该程序中我在 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
,因为在最大转弯量中有一些模拟),以便它检测到从当前航向击中 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;
}