Question

I'm working on a moltitouch application in actionscript 3, I'm also porting it in C#, Basically, im working on a Knob, that can be rotated with a finger, what i would like to achieve is that rotating CW or CCW i can have continuos direction, instead everytime angle is passing by 180 I got an inversion of direction, any hint ?

Which way can be detected a continuos rotation direction ?

this is the code I'm uding to detect direction:

private function findDirection(currentAngle : Number, targetAngle : Number) : int
{
    currentAngle = refineAngle(currentAngle);
    targetAngle = refineAngle(targetAngle);

    if (targetAngle < 0)
    {
        targetAngle +=  (Math.PI * 2);
    }

    if (currentAngle < 0)
    {
        currentAngle +=  (Math.PI * 2);
    }

    if (targetAngle < currentAngle)
    {
        targetAngle +=  (Math.PI * 2);
    }

    if (targetAngle - currentAngle <= Math.PI)
    {
        return 1;
    }
    else
    {
        return -1;
    }
}

private function refineAngle(angle : Number) : Number
{
    return angle * Math.PI / 180;
}
Was it helpful?

Solution

Maybe this helps. The variable continuousAngle will track the total knob turning performed, i.e. turning the knob twice counterclockwise will get you to 720. Then turning it three times clockwise takes you back down to -360. Everything else should be easy to derive - limiting the minimum and maximum values, making the value wrap around, scale the value to for example 1 per turn or whatever else you want.

var lastAngle = 0;

var continuousAngle = 0;

function HandleDown(angle)
{
    lastAngle = angle;
}

function HandleMove(angle)
{
    // The orientation change in degrees of the knob since the last event with
    // a range of [-180;+180). A positive value indicates counterclockwise, a
    // negative value clockwise turning.
    var change = (360 + angle - lastAngle) % 360;

    if (change >= 180)
    {
        change -= 360;
    }

    // It may also be a good idea to not update continuousAngle if the absolute
    // value of change is larger than say 10°, 20° or 40° because such large
    // changes may indicate some kind of glitch like the user moving straight
    // across the knob. But I am not sure and 20 is just a random guess.
    if (Math.Abs(change) <= 20)
    {
        continuousAngle += change;
    }

    lastAngle = angle;
}

For floating point numbers the reminder can be calculated using Math.IEEEReminder instead of the remainder operator %. The linked page also shows how to implement this function yourself if it is not available in your language.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top