Skip to content Skip to sidebar Skip to footer

Smooth 'turning' Script

I am making an HTML5 Canvas game using Javascript. I want to make an object turn smoothly to a certain direction. I am storing the direction as a variable, and using radians. The

Solution 1:

Was hoping someone would answer with an elegant solution, nothing yet so here is how I do it.

I have always found the solution to this problem very inelegant, that said, I do not know if there is a better way, nor have i endeavored to find one. Below are two functions that will return the shortest direction between two angles that derived from the function Math.atan2(yDif, xDif) which returns an angle in the range -Math.PI to Math.PI

Get shortest direction.

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

Get shortest angle

// returns the shortest angle neg angles are counterClockwise positive are clockwisefunctiongetShortestAngle(ang1, ang2){
    var cw = true; // clockwisevar 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;
}

As I loath using these functions I much prefer the slightly more complex yet more elegant solution below. This finds the shortest angle in terms of a set of 3 points. the center point, and the two points that I wish to find the angle between and it always returns the shortest angle between any two lines.

// 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) insteadfunctiongetAngleBetween(center, p1, p2){
     var d;
     var ang;
     // get vectors from center to both pointsvar 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 quadrantif(-v1.y * v2.y - v1.x * v2.x > 0){
         if(ang < 0){
            ang = -Math.PI - ang;
         }else{
            ang = Math.PI - ang;
         }
     }
     return ang;
 }

Post a Comment for "Smooth 'turning' Script"