我知道很多次都会问过这个问题,但是凭借所有的知识,我仍然无法在我现在所处的具体设置中为自己工作:Android的处理。
所涉及的坐标系是(1)根据Android视图的真实世界坐标系:y与地面相切并指向北方,z向上移动,如果你站在地上仰视北方,那么x就在你的右边; (2)按照处理视图设备坐标系:x指向屏幕右侧,y指向下方,z出现在屏幕外。
目标只是在屏幕上绘制一个立方体,并让它在设备旋转时旋转,使其看起来在实际空间中是稳定的。那就是:我想要两个坐标系之间的地图,这样我就可以用真实坐标而不是屏幕坐标来绘制。
在代码中我使用Ketai传感器库,并订阅onRotationVectorEvent(float x, float y, float z)
事件。另外,我有一个简单的四元数类,我来自https://github.com/kynd/PQuaternion。到目前为止,我有以下代码,其中我有两种不同的方法来尝试映射,但恰好相反,但仍然无法按照我的要求工作:
import ketai.sensors.*;
KetaiSensor sensor;
PVector rotationAngle = new PVector(0, 0, 0);
Quaternion rot = new Quaternion();
void setup() {
fullScreen(P3D);
sensor = new KetaiSensor(this);
sensor.start();
}
void draw() {
background(#333333);
translate(width/2, height/2);
lights();
// method 1: draw lines for real-world axes in terms of processing's coordinates
PVector rot_x_axis = rot.mult(new PVector(400, 0, 0));
PVector rot_y_axis = rot.mult(new PVector(0, 0, -400));
PVector rot_z_axis = rot.mult(new PVector(0, 400, 4));
stroke(#ffffff);
strokeWeight(8); line(0, 0, 0, rot_x_axis.x, rot_x_axis.y, rot_x_axis.z);
strokeWeight(5); line(0, 0, 0, rot_y_axis.x, rot_y_axis.y, rot_y_axis.z);
strokeWeight(2); line(0, 0, 0, rot_z_axis.x, rot_z_axis.y, rot_z_axis.z);
// method 2: first rotate appropriately
fill(#f4f7d2);
rotate(asin(rotationAngle.mag()) * 2, rotationAngle.x, rotationAngle.y, rotationAngle.z);
box(200, 200, 200);
}
void onRotationVectorEvent(float x, float y, float z) {
rotationAngle = new PVector(x, y, z);
// I believe these two do the same thing.
rot.set(x, y, z, cos(asin(rotationAngle.mag())));
//rot.setAngleAxis(asin(rotationAngle.mag())*2, rotationAngle);
}
上述效果非常好,现实世界的轴线与绘制的立方体重合,并且都以有趣的方式旋转。但是,似乎还有一些"万向节的东西"继续,从某种意义上说,当我一个方向上下旋转我的设备时,立方体也上下旋转,但站在另一个方向,立方体侧向旋转 - 好像我正在应用旋转在错误的顺序。但是,我试图通过这种方式使用四元数来避免万向节的疯狂 - 它如何仍然适用?
答案 0 :(得分:0)
我现在已经解决了,只需通过一个简单的“点击测试下一个配置”UI来测试rotate(asin(rotationAngle.mag()) * 2, <SIGN> * rotationAngle.<DIM>, <SIGN> * rotationAngle.<DIM>, <SIGN> * rotationAngle.<DIM>);
的所有可能的6 * 8配置 - 解决方案似乎为0,-1 ,2,即:
rotate(asin(rotationAngle.mag()) * 2, rotationAngle.x, -rotationAngle.y, rotationAngle.z);