Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identify clockwise or anti clockwise rotation

I have to identify whether user is making clockwise rotation gesture or anti clockwise. I have starting Vector location along with current and previous touch. Though I think starting vector can't be much use since if user can also change rotation in between. That is he could change rotation from clockwise to counter clockwise. Just like rotating d-pad of x-box. For live presentation of idea just the way Dead Trigger 2 devs did it, there is no on screen button just do rotation on screen using gestures. How can I identify it?

like image 690
Sachin Sharma Avatar asked Jan 21 '26 05:01

Sachin Sharma


1 Answers

To determine if a 2D input is rotating clockwise or anticlockwise find the cross product of the two vectors from the origin of rotation and see if it is negative or positive. One vector is from the previous input the other vector is from the current input.

In pseudo code.

centerX = screenCenterX;  // point user is rotating around
centerY = screenCenterY;
inputX = getUserX();   // gets X and Y input coords
inputY = getUserY();   //
lastVecX = inputX - centerX;  // the previous user input vector x,y
lastVecY = inputY - centerY;  //      

while(true){ // loop 
    inputX = getUserX();  // gets X and Y input coords
    inputY = getUserY();  //

    vecInX = inputX - centerX;  // get the vector from center to input
    vecInY = inputY - centerY;  // 

    // now get the cross product
    cross = lastVecX * vecInY - lastVecY * vecInX;

    if(cross > 0) then rotation is clockwise
    if(cross < 0) then rotation is anticlockwise
    if(cross == 0) then there is no rotation

    lastVecX = vecInX;  // save the current input vector
    lastVecY = vecInY;  // 
} // Loop until the cows come home.

And to get the angle you need to normalise the vectors and then the cross product is the sin of the change in angle.

In pseudo code

vecInX = inputX - centerX;  // get the vector from center to input
vecInY = inputY - centerY;  // 

// normalized input Vector by getting its length
length = sqrt(vecInX * vecInX + vecInY * vecInY);

// divide the vector by its length
vecInX /= length;
vecInY /= length;

// input vector is now normalised. IE it has a unit length

// now get the cross product
cross = lastVecX * vecInY - lastVecY * vecInX;

// Because the vectors are normalised the cross product will be in a range
// of -1 to 1 with < 0 anticlockwise and > 0 clockwise

changeInAngle = asin(cross);  // get the change in angle since last input
absoluteAngle += changeInAngle; // track the absolute angle

lastVecX = vecInX;  // save the current normalised input vector
lastVecY = vecInY;  //       
// loop
like image 85
Blindman67 Avatar answered Jan 23 '26 20:01

Blindman67