Smooth 'turning' Script
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 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;
}
Get shortest angle
// 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;
}
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) 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;
}
Post a Comment for "Smooth 'turning' Script"