私はクォータニオン チュートリアルに従っています: http://www.raywenderlich.com/12667/how-to-rotate-a-3d-object-using-touches-with-openglで、地球儀を XYZ 位置に回転させようとしています。初期クォータニオンがあり、地球の表面にランダムな XYZ 位置を生成します。その XYZ 位置を次の関数に渡します。GLKMatrix4MakeLookAt を使用して lookAt ベクターを生成し、lookAt マトリックスからスラープ ステップの終了クォータニオンを定義するというアイデアでした。
- (void)rotateToLocationX:(float)x andY:(float)y andZ:(float)z {
// Turn on the interpolation for smooth rotation
_slerping = YES; // Begin auto rotating to this location
_slerpCur = 0;
_slerpMax = 1.0;
_slerpStart = _quat;
// The eye location is defined by the look at location multiplied by this modifier
float modifier = 1.0;
// Create a look at vector for which we will create a GLK4Matrix from
float xEye = x;
float yEye = y;
float zEye = z;
//NSLog(@"%f %f %f %f %f %f",xEye, yEye, zEye, x, y, z);
_currentSatelliteLocation = GLKMatrix4MakeLookAt(xEye, yEye, zEye, 0, 0, 0, 0, 1, 0);
_currentSatelliteLocation = GLKMatrix4Multiply(_currentSatelliteLocation,self.effect.transform.modelviewMatrix);
// Turn our 4x4 matrix into a quat and use it to mark the end point of our interpolation
//_currentSatelliteLocation = GLKMatrix4Translate(_currentSatelliteLocation, 0.0f, 0.0f, GLOBAL_EARTH_Z_LOCATION);
_slerpEnd = GLKQuaternionMakeWithMatrix4(_currentSatelliteLocation);
// Print info on the quat
GLKVector3 vec = GLKQuaternionAxis(_slerpEnd);
float angle = GLKQuaternionAngle(_slerpEnd);
//NSLog(@"%f %f %f %f",vec.x,vec.y,vec.z,angle);
NSLog(@"Quat end:");
[self printMatrix:_currentSatelliteLocation];
//[self printMatrix:self.effect.transform.modelviewMatrix];
}
補間は機能し、スムーズな回転が得られますが、終了位置は入力した XYZ ではありません。これは、地球が球体であり、Lat Lon から XYZ を計算しているためです。回転後の地球の表面の緯度/経度の位置から、地球の中心に向かって「lookAt」ベクトルを直接見下ろしたいと思います。アップベクトルと関係があると思いますが、意味のあることはすべて試しました。
何が間違っているのですか - 回転が終了したときに地球の表面の XYZ にベクトルを見下ろす最終的な四元数を定義するにはどうすればよいですか? ありがとう!