使用加速度计检测压力强度 [英] Tap pressure strength detection using accelerometer
问题描述
昨天,在关于iPad 2的新Garageband的演示中,Apple演示了一个有趣的功能:使用加速度计检测分接压力。 (请参阅 Garageband页面上的鼓部分。)
Yesterday, in the presentation about the new Garageband for iPad 2, Apple demoed an interesting feature: The detection of the tap pressure by using the accelerometer. (See the drums section on the Garageband page.)
我想知道如果iPad放在桌子上,这应该是怎么回事。没有运动,没有可测量的加速度,没有?
I'm wondering how that's supposed to work if the iPad lays flat on the table. No movement, no measurable acceleration, no?
推荐答案
一些好的答案。这是一些有效的代码。我将其实现为UIGestureRecognizer的子类,以便您可以将其删除并将其附加到UIView或UIButton。一旦触发,它将压力设置为介于0.0f和2.0f之间的浮点数。您可以选择设置识别所需的最小和最大压力。享受。
Some good answers. Here's some working code. I implemented this as a subclass of UIGestureRecognizer so that you can just drop it in and attach it to a UIView or UIButton. Once triggered, it will have the "pressure" set to a float between 0.0f and 2.0f. You can optionally set the minimum and maximum pressures required to recognize. Enjoy.
//
// CPBPressureTouchGestureRecognizer.h
// PressureSensitiveButton
//
// Created by Anthony Picciano on 3/21/11.
// Copyright 2011 Anthony Picciano. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#import <UIKit/UIKit.h>
#define CPBPressureNone 0.0f
#define CPBPressureLight 0.1f
#define CPBPressureMedium 0.3f
#define CPBPressureHard 0.8f
#define CPBPressureInfinite 2.0f
@interface CPBPressureTouchGestureRecognizer : UIGestureRecognizer <UIAccelerometerDelegate> {
@public
float pressure;
float minimumPressureRequired;
float maximumPressureRequired;
@private
float pressureValues[30];
uint currentPressureValueIndex;
uint setNextPressureValue;
}
@property (readonly, assign) float pressure;
@property (readwrite, assign) float minimumPressureRequired;
@property (readwrite, assign) float maximumPressureRequired;
@end
//
// CPBPressureTouchGestureRecognizer.h
// PressureSensitiveButton
//
// Created by Anthony Picciano on 3/21/11.
// Copyright 2011 Anthony Picciano. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#import <UIKit/UIGestureRecognizerSubclass.h>
#import "CPBPressureTouchGestureRecognizer.h"
#define kUpdateFrequency 60.0f
#define KNumberOfPressureSamples 3
@interface CPBPressureTouchGestureRecognizer (private)
- (void)setup;
@end
@implementation CPBPressureTouchGestureRecognizer
@synthesize pressure, minimumPressureRequired, maximumPressureRequired;
- (id)initWithTarget:(id)target action:(SEL)action {
self = [super initWithTarget:target action:action];
if (self != nil) {
[self setup];
}
return self;
}
- (id)init {
self = [super init];
if (self != nil) {
[self setup];
}
return self;
}
- (void)setup {
minimumPressureRequired = CPBPressureNone;
maximumPressureRequired = CPBPressureInfinite;
pressure = CPBPressureNone;
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0f / kUpdateFrequency];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
}
#pragma -
#pragma UIAccelerometerDelegate methods
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
int sz = (sizeof pressureValues) / (sizeof pressureValues[0]);
// set current pressure value
pressureValues[currentPressureValueIndex%sz] = acceleration.z;
if (setNextPressureValue > 0) {
// calculate average pressure
float total = 0.0f;
for (int loop=0; loop<sz; loop++) total += pressureValues[loop];
float average = total / sz;
// start with most recent past pressure sample
if (setNextPressureValue == KNumberOfPressureSamples) {
float mostRecent = pressureValues[(currentPressureValueIndex-1)%sz];
pressure = fabsf(average - mostRecent);
}
// caluculate pressure as difference between average and current acceleration
float diff = fabsf(average - acceleration.z);
if (pressure < diff) pressure = diff;
setNextPressureValue--;
if (setNextPressureValue == 0) {
if (pressure >= minimumPressureRequired && pressure <= maximumPressureRequired)
self.state = UIGestureRecognizerStateRecognized;
else
self.state = UIGestureRecognizerStateFailed;
}
}
currentPressureValueIndex++;
}
#pragma -
#pragma UIGestureRecognizer subclass methods
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
setNextPressureValue = KNumberOfPressureSamples;
self.state = UIGestureRecognizerStatePossible;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
self.state = UIGestureRecognizerStateFailed;
}
- (void)reset {
pressure = CPBPressureNone;
setNextPressureValue = 0;
currentPressureValueIndex = 0;
}
@end
这篇关于使用加速度计检测压力强度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!