iphone - Tap pressure strength detection using accelerometer -
yesterday, in presentation new garageband ipad 2, apple demoed interesting feature: detection of tap pressure using accelerometer. (see drums section on garageband page.)
i'm wondering how that's supposed work if ipad lays flat on table. no movement, no measurable acceleration, no?
some answers. here's working code. implemented subclass of uigesturerecognizer can drop in , attach uiview or uibutton. once triggered, have "pressure" set float between 0.0f , 2.0f. can optionally set minimum , maximum pressures required recognize. enjoy.
// // cpbpressuretouchgesturerecognizer.h // pressuresensitivebutton // // created anthony picciano on 3/21/11. // copyright 2011 anthony picciano. rights reserved. // // redistribution , use in source , binary forms, or without // modification, permitted provided following conditions // met: // 1. redistributions of source code must retain above copyright // notice, list of conditions , following disclaimer. // 2. redistributions in binary form must reproduce above copyright // notice, list of conditions , following disclaimer in // documentation and/or other materials provided distribution. // // software provided author ``as is'' , express or // implied warranties, including, not limited to, implied warranties // of merchantability , fitness particular purpose disclaimed. // in no event shall author liable direct, indirect, // incidental, special, exemplary, or consequential damages (including, // not limited to, procurement of substitute goods or services; loss of use, // data, or profits; or business interruption) caused , on // theory of liability, whether in contract, strict liability, or tort // (including negligence or otherwise) arising in way out of use of // software, if advised of 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 anthony picciano on 3/21/11. // copyright 2011 anthony picciano. rights reserved. // // redistribution , use in source , binary forms, or without // modification, permitted provided following conditions // met: // 1. redistributions of source code must retain above copyright // notice, list of conditions , following disclaimer. // 2. redistributions in binary form must reproduce above copyright // notice, list of conditions , following disclaimer in // documentation and/or other materials provided distribution. // // software provided author ``as is'' , express or // implied warranties, including, not limited to, implied warranties // of merchantability , fitness particular purpose disclaimed. // in no event shall author liable direct, indirect, // incidental, special, exemplary, or consequential damages (including, // not limited to, procurement of substitute goods or services; loss of use, // data, or profits; or business interruption) caused , on // theory of liability, whether in contract, strict liability, or tort // (including negligence or otherwise) arising in way out of use of // software, if advised of 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; (int loop=0; loop<sz; loop++) total += pressurevalues[loop]; float average = total / sz; // start recent past pressure sample if (setnextpressurevalue == knumberofpressuresamples) { float mostrecent = pressurevalues[(currentpressurevalueindex-1)%sz]; pressure = fabsf(average - mostrecent); } // caluculate pressure difference between average , 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
Comments
Post a Comment