Shake Detection

,

The phone SDK does not come with any built-in support for detecting when the device is being shaken. This section extends the custom EnhancedAccelerometer to provide shake detection.

The EnhancedAccelerometer.IsShake method returns true if the difference between the current and previous acceleration readings exceeds a threshold value for two or more dimensional components, in which case, the movement is deemed a shake. Thanks to Mark Monster, http://bit.ly/9GMDJX, on which this code is based. See the following excerpt:

static bool IsShake(Vector3 currentAcceleration,
                    Vector3 previousAcceleration, double threshold)
{
    double deltaX = Math.Abs(previousAcceleration.X - currentAcceleration.X);
    double deltaY = Math.Abs(previousAcceleration.Y - currentAcceleration.Y);
    double deltaZ = Math.Abs(previousAcceleration.Z - currentAcceleration.Z);

    return deltaX > threshold && deltaY > threshold
            || deltaX > threshold && deltaZ > threshold
            || deltaY > threshold && deltaZ > threshold;
}

A Shake event has been added to the IAccelerometer interface. When a new reading is received from the Accelerometer within the EnhancedAccelerometer, the DetectShake method is called (see Listing 16.3). If a shake is detected, the Shake event is raised.

Two threshold properties control sensitivity during shake detection. Both threshold properties are of type double, representing the threshold in radians. The first, ShakeThreshold, is used to determine when a shake has begun; the second, ShakeEndThreshold, defines the maximum value of the acceleration delta, used for detecting when the device is no longer being shaken.

LISTING 16.3. EnhancedAccelerometer.DetectShake Method


void DetectShake(Vector3 acceleration)
{
    EventHandler tempEvent = Shake;

    if (tempEvent == null || !previousAcceleration.HasValue)
    {
        return;
    }

    Vector3 previousValue = previousAcceleration.Value;
    bool shakeDetected = IsShake(acceleration, previousValue, shakeThreshold);

    if (shakeDetected && !shaking && shakeCount > 0)
    {
        shaking = true;
        shakeCount = 0;
        OnShake(EventArgs.Empty);
    }
    else if (shakeDetected)
    {
        shakeCount++;
    }
    else if (!IsShake(acceleration, previousValue, shakeEndThreshold))
    {
        shakeCount = 0;
        shaking = false;
    }
}


The AccelerometerViewModel subscribes to the IAccelerometer.Shake event. When the event is raised, the viewmodel’s ShakeCount property is incremented. ShakeCount is displayed using a TextBlock, as shown:

<TextBlock Text="{Binding ShakeCount, StringFormat='{0} shakes'}"
                       Style="{StaticResource LabelTextStyle}"
                       Foreground="{StaticResource PhoneAccentBrush}"
                       HorizontalAlignment="Right" />

All Windows Phone devices are required to have an accelerometer, and the accelerometer API has been present since the first release of the phone SDK. It is, therefore, a staple piece of Windows Phone tech that offers a reliable way of enriching your app with movement sensing.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.48.3