我试图弄清楚如何得到一个OpenGL根据设备取向(即,根据来自加速度计的重力矢量,和从罗盘航向)指定的对象被正确显示。

在GLGravity示例项目具有其一个例子是几乎像这样(尽管忽略标题),但它有一些毛刺。例如,茶壶跳180deg为视角的装置越过地平线,如果你从纵向倾斜设备到景观也旋转不合逻辑。这是这个应用程序的情况下罚款,因为它只是展示了一个对象,它并不重要,它做这些事。但这也意味着,该代码只是当你试图模仿现实生活中根据设备的方向观看一个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;

这是克里斯的建议跟进:我不知道,如果我有了这个正确的,由于不同的行/列顺序的惯例和方向顺时针或逆时针。然而,下面的代码是什么,我想出了:

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);

当运行此代码,茶壶行为显然已经“改善的”,例如。标题不再翻转180deg当设备的屏幕(在纵向视图)被金字前进/后退通过直立。然而,它仍然使大跳跃时,装置(横向视图)中投前进/后退前进。因此,一些不正确的。这表明,上述的实际标题的计算是不正确...

没有正确的解决方案

其他提示

我终于找到一个可行的解决方案。 : - )

我下降旋转矩阵的方法,以及采用代替gluLookAt。为了使这项工作,你需要知道设备的“海拔”(观察相对角度地平线即0上地平线,+90开销),和相机的“倾斜”(多远的设备是从垂直的X / Y平面即。0当垂直/肖像,+/- 90时水平/横向),这两者都是从所述设备的重力矢量分量而获得。

Vector3D eye, scene, up;
CGFloat distanceFromScene = 0.8;
// Adjust eye position for elevation (y/z)
eye.x = 0;
eye.y = distanceFromScene * -sin(elevationRadians); // eye position goes down as elevation angle goes up
eye.z = distanceFromScene * cos(elevationRadians);  // z position is maximum when elevation is zero 
// Lookat point is origin
scene = Vector3DMake(0, 0, 0); // Scene is at origin
// Camera tilt - involves x/y plane only - arbitrary vector length
up.x = sin(tiltRadians);
up.y = cos(tiltRadians);
up.z = 0;

然后你只需根据设备标题应用gluLookAt改造,还旋转了现场。

// Adjust view for device orientation
gluLookAt(eye.x, eye.y, eye.z, scene.x, scene.y, scene.z, up.x, up.y, up.z);
// Apply device heading to scene
glRotatef(currentHeadingDegrees, 0.0, 1.0, 0.0);

尝试旋转取决于iphone加速度值的对象。

float angle = -atan2(accelX, accelY);

glPushMatrix();     
glTranslatef(centerPoint.x, centerPoint.y, 0);
glRotatef(angle, 0, 0, 1);
glTranslatef(-centerPoint.x, -centerPoint.y, 0);
glPopMatrix();

其中中心点的中间点的对象。

OO,美观大方。

GLGravity似乎得到除偏航的一切权利。下面是我想尝试。尽一切GLGravity做,然后这样的:

项目,你的方向的矢量想的茶壶到面,共使用指南针或任何你选择这样做。然后乘以一“向前”向量由茶壶的当前旋转矩阵,这将给你的方向上的茶壶的就是面对。拼合两个向量于水平面并把它们之间的角度。

此角度是你的纠正偏航。然后,只需通过它glRotatef

无论是否3GS的指南针是这个工作可靠和足够强大的是另一回事。当北方的矢量垂直于他们的脸普通罗盘不起作用。但我只是想在我的同事的3GS的地图应用程序,它似乎应付,所以也许他们已经得到了在那里的机械解决方案。知道什么该设备实际上做将有助于解释它给出了结果。

请确保在南北两极,以测试你的应用程序,一旦你就大功告成了。 : - )

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top