
http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation#Quaternion_from_axis-angle

matrix3x3 viewMatrix{
worldAxisX.x, worldAxisX.y, worldAxisX.z,worldAxisY.x, worldAxisY.y, worldAxisY.z,worldAxisZ.x, worldAxisZ.y, worldAxisZ.z
};or matrix4x4matrix4x4 viewMatrix{
worldAxisX.x, worldAxisX.y, worldAxisX.z, 0worldAxisY.x, worldAxisY.y, worldAxisY.z, 0worldAxisZ.x, worldAxisZ.y, worldAxisZ.z, 00, 0, 0, 1
}
| SAMPLE CODE | |
|---|---|
| declaration | UIAccelerationValue accelerationX; UIAccelerationValue accelerationY; UIAccelerationValue accelerationZ; CLHeadingComponentValue headingX; CLHeadingComponentValue headingY; CLHeadingComponentValue headingZ; |
| constant | const double lowpassFilter = 0.1f; const double IGL_PI = 3.14159265358979323846f; |
| getting device-heading | - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { if (newHeading.headingAccuracy > 0) { headingX = headingX * (1.0f - lowpassFilter) + newHeading.x * lowpassFilter; headingY = headingY * (1.0f - lowpassFilter) + newHeading.y * lowpassFilter; headingZ = headingZ * (1.0f - lowpassFilter) + newHeading.z * lowpassFilter; } } |
| getting gravity-direction | - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { accelerationX = accelerationX * (1.0f - lowpassFilter) + acceleration.x * lowpassFilter; accelerationY = accelerationY * (1.0f - lowpassFilter) + acceleration.y * lowpassFilter; accelerationZ = accelerationZ * (1.0f - lowpassFilter) + acceleration.z * lowpassFilter; } |
| calculating view matrix | IGMatrix3 IGApplicationContextImpl::GetSystemRotation(void) const { if ([[UIApplication sharedApplication].delegate isKindOfClass:[IGApplicationDelegate class]]) { IGApplicationDelegate* appDelegate = (IGApplicationDelegate*)[UIApplication sharedApplication].delegate; IGVector3 deviceHeading = IGVector3(appDelegate.headingX, appDelegate.headingY, appDelegate.headingZ).Normalize(); IGVector3 deviceGravity = IGVector3(appDelegate.accelerationX, appDelegate.accelerationY, appDelegate.accelerationZ).Normalize(); // 로컬 좌표를 gravity 로 변환하기 위한 타겟 (중력과 가까운 y 축 방향으로 설정한다) IGVector3 rotationTarget = IGVector3::Dot(IGVector3(0,1,0), deviceGravity) > 0.0 ? IGVector3(0,1,0) : IGVector3(0,-1,0); // 로컬좌표가 gravity 로 이동하는 회전을 구한다. IGQuaternion localToGravity(IGVector3::Cross(rotationTarget, deviceGravity), acos(IGVector3::Dot(rotationTarget, deviceGravity))); // rightAngledHeading: 중력방향과 직각을 이루는 북쪽(heading) IGVector3 rightAngledHeading = deviceHeading * IGQuaternion(localToGravity).Inverse(); // heading 을 로컬 좌표로 변환한다. rightAngledHeading.y = 0; // 로컬 heading 을 x,z 평면으로 프로젝션 rightAngledHeading.Rotate(localToGravity); // 다시 현실 좌표로 원위치 (이제 중력과 직각이 된다) IGVector3 worldAxisY = IGVector3(-deviceGravity); IGVector3 worldAxisZ = IGVector3(-rightAngledHeading).Normalize(); IGVector3 worldAxisX = IGVector3::Cross(worldAxisY, worldAxisZ).Normalize(); // X 축 좌표는 Y 축과 Z 축의 외적 IGMatrix3 deviceRotate = IGMatrix3::identity; switch ([(IGApplicationViewController*)appDelegate.viewController orientation]) { case UIInterfaceOrientationPortraitUpsideDown: deviceRotate *= IGLinearTransform3().Identity().Rotate(IGVector3(0,0,1), IGL_PI); break; case UIInterfaceOrientationLandscapeLeft: deviceRotate *= IGLinearTransform3().Identity().Rotate(IGVector3(0,0,-1), IGL_PI/2); break; case UIInterfaceOrientationLandscapeRight: deviceRotate *= IGLinearTransform3().Identity().Rotate(IGVector3(0,0,1), IGL_PI/2); break; } return IGMatrix3(worldAxisX, worldAxisY, worldAxisZ) * deviceRotate; } return IGMatrix3().Identity(); } |
| Note | IGApplicationDelegate is just UIApplicationDelegate object (not important whatever), just keep tracking device orientation. IGVector3 is vector3 object (contains float x,y,z) IGQuaternion is quaternion object (contains float x,y,z,w). You must be able to build with rotation angle, axis IGMatrix3 is matrix 3x3 object. |
Comments
Manoj (unauthenticated)
Feb 13, 2011
Thanks a ton :-)