私はiOS用のOpenGL ES 2.0を学んでおり、いくつかのチュートリアルの助けを借りて、クォータニオンを使用して単純な球体オブジェクトを回転およびズームできます。ユーザーがスワイプを完了した後に画面から指を離したときに、球体が速度を落としながら回転し続けるようにしたいので、球体に勢いをつけたいと思います。このブログを使用して、回転について学びました: http://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-opengl . 誰かが勢いのいくつかの読書や例を提供できますか? 四元数で運動量を実装するにはどうすればよいですか? ありがとう!
// Set up the frustrum and projection matrix
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
// Now perform the interpolation step
//[self slerpToNewLocation];
// Move the globe back so we can see it
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, GLOBAL_EARTH_Z_LOCATION);
// In update, we convert the quaternion into a rotation matrix, and apply it to the model view matrix as usual.
GLKMatrix4 rotation = GLKMatrix4MakeWithQuaternion(_quat);
GLKMatrix4 rotateMatrix = GLKMatrix4RotateWithVector3(rotation,momentumVar/200,GLKQuaternionAxis(_quat));
_quat = GLKQuaternionMakeWithMatrix4(rotateMatrix);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, rotateMatrix);
// Cap the zoom scale factor max and mins
// only if slerping so that the auto-zoom out and back
// in still works during auto-rotation
if ( !_slerping ) {
if ( scale > 2.0 ) {
scale = 2.0;
}
if ( scale < 1.15 ) {
scale = 1.15;
}
}
// Apply the zoom factors
if ( _slerping ) {
//NSLog(@"final scale %f",scale);
}
modelViewMatrix = GLKMatrix4Scale(modelViewMatrix, scale, scale, scale);
// Assign the drawer modelViewMatrix
self.effect.transform.modelviewMatrix = modelViewMatrix;
次の質問を見ました: ここでいくつかのヒントをいただければ幸いです-ありがとう。
// Called when touches are ended
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
// The momentum var is initialized to a value
momentumVar = 0.025;
// Now since we stopped touching, decay the rotation to simulate momentum
momentumTimer = [NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:@selector(decayGLKQuaternion)
userInfo:nil
repeats:YES];
}
// Slerp about the current axis after touches ended but for a greater angle ( radians )
- (void)decayGLKQuaternion {
if ( momentumVar < 0.001 ) {
// Stop the momentum and timer
momentumVar = 1.0;
[momentumTimer invalidate];
}
else {
// What is the current angle for the quaternion?
float currentQuatAngle = GLKQuaternionAngle(_quat);
// Decay the value each time
momentumVar = currentQuatAngle * 0.95;
}
}
更新:私はまだこれを理解しようとしています.更新メソッドの現在のクォータニオンをMatrix4に変換し、そのマトリックスをクォータニオン軸を中心に回転させて、TouchesEnded内で起動を開始するタイマーから更新およびデクリメントされる値を取得しようとしました私のアプリ。結果は回転しますが、軸は正しく見えず (近いようです)、角度は予想とは反対の回転方向を作成します。したがって、下にスワイプして指を離すと、地球は減速しながら上向きに回転します。角度値の符号を変更しても役に立ちません。クォータニオンから回転軸を正しく抽出し、適切な角度で回転させ、速度を下げて回転させるにはどうすればよいですか? ありがとう -
// In update, we convert the quaternion into a rotation matrix, and apply it to the model view matrix as usual.
GLKMatrix4 rotation = GLKMatrix4MakeWithQuaternion(_quat);
GLKMatrix4 rotateMatrix = GLKMatrix4RotateWithVector3(rotation,momentumVar/200,GLKQuaternionAxis(_quat));
_quat = GLKQuaternionMakeWithMatrix4(rotateMatrix);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, rotateMatrix);