2016-06-13 41 views
0

我在制作一个使用Javascript的HTML5 Canvas游戏。流畅的'转向'脚本

我想让一个对象顺利地转向某个方向。

我将方向存储为变量,并使用弧度。该代码是这样的:

window.setInterval(loop,25); 
 

 
var dir = 0; 
 
var targetDir = Math.PI/2; 
 

 
function loop() { 
 
    dir += (targetDir - dir)/5; 
 
    document.getElementById('text').innerHTML = dir; //To display the direction 
 
}
<p id='text'></p>

将工作的大部分时间,但如果方向和目标方向上相对的左侧/右侧,计算机将承担以最快的方式到达目标是一路走来,像这样: (Image)

有没有人知道一个算法,我可以使它正常工作?

回答

1

希望有人会回答一个优雅的解决方案,什么都没有,所以这里是我如何做到这一点。

我总是发现这个问题的解决方案很不雅,说,我不知道是否有更好的方法,也没有我努力找到一个。下面是两个函数将返回由函数Math.atan2(yDif, xDif)返回在范围内的角度得出两个角度之间的最短方向 - Math.PIMath.PI

获取最短方向。

// returns true if shortest direction is clockwise else false 
function isShortestDirClockwise(ang1, ang2){ 
    if (ang1 < 0) { 
     if ((ang2 < 0 && ang1 > ang2) || (ang2 >= 0 && ang1 + Math.PI < ang2)) { 
      return false;   
     } 
    } else { 
     if ((ang2 > 0 && ang1 > ang2) || (ang2 <= 0 && ang1 - Math.PI < ang2)) { 
      return false;   
     } 
    } 
    return true; 
} 

找最短的角度

// returns the shortest angle neg angles are counterClockwise positive are clockwise 
function getShortestAngle(ang1, ang2){ 
    var cw = true; // clockwise 
    var ang; 
    if (ang1 < 0) { 
     if((ang2 < 0 && ang1 > ang2) || (ang2 >= 0 && ang1 + Math.PI < ang2)) { 
      cw = false;   
     } 
    } else { 
     if ((ang2 > 0 && ang1 > ang2) || (ang2 <= 0 && ang1 - Math.PI < ang2)) { 
      cw = false;   
     } 
    } 
    if (cw) { 
     var ang = ang2 - ang1; 
     if (ang < 0) { 
      ang = ang2 + Math.PI * 2 - ang1; 
     } 
     return ang; 
    } 
    var ang = ang1 - ang2; 
    if (ang < 0) { 
     ang = ang1 + Math.PI * 2 - ang2; 
    } 
    return -ang; 
} 

正如我不愿意使用这些功能,我更喜欢下面稍微复杂但更优雅的解决方案。这根据一组3点找出最短角度。中心点以及我希望找到两个角度之间的角度的两点,它总是返回任意两条线之间的最短角度。

// Warning may return NAN if there is no solution (ie one or both points (p1,p2) are at center) 
// Also uses Math.hypot check browser compatibility if you wish to use this function or use Math.sqrt(v1.x * v1.x + v1.y * v1.y) instead 
function getAngleBetween(center, p1, p2){ 
    var d; 
    var ang; 
    // get vectors from center to both points 
    var v1 = { x : p1.x - center.x, y : p1.y - center.y}; 
    var v2 = { x : p2.x - center.x, y : p2.y - center.y}; 
    // normalise both vectors 
    d = Math.hypot(v1.x, v1.y); 
    v1.x /= d; 
    v1.y /= d; 
    d = Math.hypot(v2.x, v2.y); 
    v2.x /= d; 
    v2.y /= d; 
    // cross product gets the angle in range -Math.PI/2 to Math.PI/2 
    ang = Math.asin(v1.x * v2.y - v1.y * v2.x); 
    // use the cross product of the line perpendicular to the first to find the quadrant 
    if(-v1.y * v2.y - v1.x * v2.x > 0){ 
     if(ang < 0){ 
      ang = -Math.PI - ang; 
     }else{ 
      ang = Math.PI - ang; 
     } 
    } 
    return ang; 
} 
+0

谢谢你的帮助!不过,我会保留这个问题'没有答案',以防万一有人提到你所说的'优雅的解决方案'。 –