Cube这个项目做了将近一个月了吧,最后一个重要的功能模块就是手势识别,这个做好了将为"2010 Google Android 应用开发中国大学生挑战赛"增加一个胜的砝码。手势识别很简单,只需重载方法就行了。麻烦的是Opengl ES中的glRotatef(float angle , float x , float y , float z)。这个函数和Opengl中的glRotatef(float angle , float x , float y , float z)这个函数不同。
我查了一下Opengl下的glRotatef()。angle表示转过的角度,旋转方向满足右手螺旋定则;后面三个参数合起来的(x , y , z)向量,表示转轴。在屏幕中,上 下为y轴,上为正向;左右为x轴,右为正向;里外为z轴,外为正向。因为Opengl ES这方面的资料目前比较稀缺,又因为ES是Opengl的一个简化版本,所以我就想,ES下的glRotatef()也是这个用法吧。
但是,我大大的错了!
ES中的glRotatef()和Opengl下的glRotatef()用法是不同的。
我的开发机器是MailStone,至少在mailstone中,下为y轴正向,这一点不同。还有一点,角度的旋转方向不满足右手螺旋定则。其具有以下特性:在x正方向满足右手定则,在y轴负方向满足右手定则。因为是在手机二维屏幕上测试,所以z轴没测试。
其测试代码如下:
public class MyGesture extends Activity { private GestureDetector mGestureDetector ; private OnTouchListener mGestureListener ; private boolean mIsScrolling = false ; private LinearLayout aLayout ; @Override public void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ) ; setContentView( R.layout.main ) ; aLayout = ( LinearLayout ) findViewById( R.id.aLinerLayout ) ; mGestureDetector = new GestureDetector( new SimpleOnGestureListener() { @Override public boolean onScroll( MotionEvent e1 , MotionEvent e2 , float distanceX , float distanceY ) { mIsScrolling = true ; if( Math.abs( e2.getY() - e1.getY() ) < 0.1 ) { if( e2.getX() - e1.getX() > 0 ) { Log.i( "direction" , "right" ) ; } else if( e2.getX() - e1.getX() < 0 ) { Log.i( "direction" , "left" ) ; } } else if( Math.abs( e2.getX() - e1.getX() ) < 0.1 ) { if( e2.getY() - e1.getY() > 0 ) { Log.i( "direction" , "down" ) ; Log.i( "sdfsdf" , String.valueOf( e2.getY() - e1.getY() ) ) ; } else if( e2.getY() - e1.getY() < 0 ) { Log.i( "direction" , "up" ) ; Log.i( "sdfsdf" , String.valueOf( e2.getY() - e1.getY() ) ) ; } } else if( ( e2.getX() - e1.getX() > 0 ) && ( e2.getY() - e1.getY() < 0 ) ) { Log.i( "direction" , "right-up" ) ; } else if( ( e2.getX() - e1.getX() < 0 ) && ( e2.getY() - e1.getY() < 0 ) ) { Log.i( "direction" , "left-up" ) ; } else if( ( e2.getX() - e1.getX() < 0 ) && ( e2.getY() - e1.getY() > 0 ) ) { Log.i( "direction" , "left-down" ) ; } else if( ( e2.getX() - e1.getX() > 0 ) && ( e2.getY() - e1.getY() > 0 ) ) { Log.i( "direction" , "right-down" ) ; } return true ; } @Override public boolean onDown( MotionEvent e ) { Log.d( "123" , "GestureDetector --> onDown" ) ; return true ; } } ) ; mGestureListener = new View.OnTouchListener() { public boolean onTouch( View v , MotionEvent event ) { if( mGestureDetector.onTouchEvent( event ) ) { return true ; } if( event.getAction() == MotionEvent.ACTION_UP ) { if( mIsScrolling ) { Log.d( "end" , "OnTouchListener --> onTouch ACTION_UP" ) ; mIsScrolling = false ; } } return false ; } } ; aLayout.setOnTouchListener( mGestureListener ) ; } }
可以看到,当手指在屏幕上向右滑动时,两个MotionEvent之间的x坐标之差为正;当手指在屏幕上 向下滑动时,两个MotionEvent之间的y坐标之差为正。这个可以通过LogCat看到。
参考:http://hi.baidu.com/zqw19891001/blog/item/79a6a4ef3bcc0d1ffcfa3c25.html/cmtid/d8aa78cb78903b12bf09e620