Search code examples
rotationlinear-algebragame-physics

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?


Solution

  • 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