[我正在尝试找出如何根据设备方向(即,根据加速度计的重力矢量和指南针的方向)正确显示OpenGL指定的对象。
GLGravity示例项目有一个几乎像这样的示例(尽管忽略了标题),但是存在一些故障。例如,当设备的视角越过地平线时,茶壶会跳180度;如果将设备从纵向倾斜到横向,茶壶也会旋转。这对于此应用程序的上下文来说是很好的,因为它只是显示一个对象,而执行这些操作并不重要。但这意味着,当您尝试根据设备的方向模拟OpenGL对象的真实视图时,该代码将无法正常工作。发生的事情是,它几乎可以正常工作,但是您从指南针应用的航向旋转由于在GLGravity示例项目中看到的虚假附加旋转而“损坏”。
任何人都可以提供示例代码来显示如何针对设备方向(即重力矢量)进行正确调整,或修复GLGravity示例,使其不包括虚假的航向变化吗?
//Clear matrix to be used to rotate from the current referential to one based on the gravity vector
bzero(matrix, sizeof(matrix));
matrix[3][3] = 1.0;
//Setup first matrix column as gravity vector
matrix[0][0] = accel[0] / length;
matrix[0][1] = accel[1] / length;
matrix[0][2] = accel[2] / length;
//Setup second matrix column as an arbitrary vector in the plane perpendicular to the gravity vector {Gx, Gy, Gz} defined by by the equation "Gx * x + Gy * y + Gz * z = 0" in which we arbitrarily set x=0 and y=1
matrix[1][0] = 0.0;
matrix[1][1] = 1.0;
matrix[1][2] = -accel[1] / accel[2];
length = sqrtf(matrix[1][0] * matrix[1][0] + matrix[1][1] * matrix[1][1] + matrix[1][2] * matrix[1][2]);
matrix[1][0] /= length;
matrix[1][1] /= length;
matrix[1][2] /= length;
//Setup third matrix column as the cross product of the first two
matrix[2][0] = matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1];
matrix[2][1] = matrix[1][0] * matrix[0][2] - matrix[1][2] * matrix[0][0];
matrix[2][2] = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
//Finally load matrix
glMultMatrixf((GLfloat*)matrix);
这里是一个说明,显示了如何获取gluLookAt解决方案所需的高程和倾斜度,如我最后一个答案所示:
// elevation comes from z component (0 = facing horizon)
elevationRadians = asin(gravityVector.z / Vector3DMagnitude(gravityVector));
// tilt is how far screen is from vertical, looking along z axis
tiltRadians = atan2(-gravityVector.y, -gravityVector.x) - M_PI_2;
按照Chris的建议:由于行/列顺序和标题cw或ccw的约定不同,我不确定是否都正确。但是下面的代码是我想出的:
Vector3D forward = Vector3DMake(0.0f, 0.0f, -1.0f);
// Multiply it by current rotation matrix to get teapot direction
Vector3D direction;
direction.x = matrix[0][0] * forward.x + matrix[1][0] * forward.y + matrix[2][0] * forward.z;
direction.y = matrix[0][1] * forward.x + matrix[1][1] * forward.y + matrix[2][1] * forward.z;
direction.z = matrix[0][2] * forward.x + matrix[1][2] * forward.y + matrix[2][2] * forward.z;
heading = atan2(direction.z, direction.x) * 180 / M_PI;
// Use this heading to adjust the teapot direction back to keep it fixed
// Rotate about vertical axis (Y), as it is a heading adjustment
glRotatef(heading, 0.0, 1.0, 0.0);
[当我运行此代码时,茶壶的行为显然已“得到改善”,例如。当设备屏幕(纵向视图)通过竖直向前/向后倾斜时,航向不再翻转180度。但是,当设备(在横向视图中)向前/向后倾斜时,它仍会在航向上产生较大的跳跃。所以不对劲。这表明以上对实际航向的计算不正确...