使用设备方向与3D变换

4
有一个项目要实现一个立方体,其六个面对应东/西/上/地面/北/南,并且这些面应始终指向相应的地理位置。所需数据从deviceorientation API中获取:http://cube.ffos.lolcathost.org/ 我和许多其他用户想知道为什么这个应用程序没有按照预期运行(它应该在Firefox OS上运行,或者在任何带有Firefox的Android设备上运行)。除了代码似乎执行了许多不必要的操作以及编程风格很糟糕之外,我并不太明白他在那里做什么。
然后我发现MDN上有如何进行类似操作的提示:https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Using_device_orientation_with_3D_transforms 这两种方法显然都是错误的:它们认为你可以通过简单地按正确顺序应用rotateXrotateYrotateZ来反转设备方向。
但是deviceorientation事件提供了角度(alpha,beta,gamma)的清晰定义:http://www.w3.org/TR/orientation-event/#deviceorientation,并且它说相应的旋转轴是旋转(设备)框架的轴。因此,您需要围绕z轴旋转角度alpha,然后围绕(现在旋转的!)x轴旋转角度beta,然后围绕(现在旋转了两次的!)y轴旋转角度gamma。
由于对于CSS变换,参考系总是设备框架,要反转这些步骤,您需要手动保持旋转轴的旋转。
var b = e.beta,
    g = -e.gamma,
    a = e.alpha,
    axis_y = Array(0,1,0),
    axis_x = rotate(Array(1,0,0), axis_y, g),
    axis_z = rotate(rotate(Array(0,0,1), axis_y, g), axis_x, b);

因此,CSS 变换的代码如下所示:
document.getElementById("cube").style.transform =
    "rotate3d(" + axis_z[0] + ", " + axis_z[1] + ", " + axis_z[2] + ", " + a + "deg) " +
    "rotate3d(" + axis_x[0] + ", " + axis_x[1] + ", " + axis_x[2] + ", " + b + "deg) " +
    "rotate3d(" + axis_y[0] + ", " + axis_y[1] + ", " + axis_y[2] + ", " + g + "deg)";

请注意,对于CSS变换函数rotate3d,“当从轴向量末端往原点看时,旋转是顺时针的”,而对于提供的alpha-beta-gamma,“绕轴的正向旋转是顺时针的”。考虑到CSS变换的y轴指向屏幕底部,我们只需要在我们的上下文中反转gamma角度即可。
这是我实现的方式:http://tovotu.de/tests/compass/index.html 我的问题是:这是实现这一目标的正确/最佳方法吗?还是有一种方法可以在不多次旋转旋转轴的情况下完成它?

有趣的是,在Chrome桌面版本47.0.2526.80 m上,与其在屏幕上显示“..您的设备没有方向传感器..”消息,而是显示了立方体,并且所有3个坐标都具有值0。当我的屏幕100%没有方向传感器时,Chrome如何显示0? Chrome不应该为这些值显示null,从而也显示“..不支持..”消息吗? https://stackoverflow.com/questions/35093857/device-orientation-api-returns-different-values-for-desktop-browsers - lowtechsun
1个回答

1
我自己在玩Device Orientation API时只是涉及到了表面 - 我独立获取beta和gamma值,并将它们应用于球的速度以在使用Phaser框架创建的名为Cyber Orb的简单游戏演示中滚动屏幕,该演示使用Canvas进行渲染(您可以在MDN文章Mozilla Hacks帖子中找到更多详细信息)。
CSS 3D变换实际上不是我的专业领域,但我认为 - 如果它能正常工作,那就直接使用。它看起来非常简单并且能够完成工作,所以没有必要过于复杂化。如果有人知道更好的方法,我也想看看。

谢谢你的回答。不幸的是,我只有一部手机可以运行我的代码。而且在这部手机上,当我把手机倒过来(屏幕朝向地面)时,魔方会表现得很奇怪。可能是手机的传感器或传感器驱动程序或我的实现有问题...但值得注意的是,在“大多数”情况下,魔方的表现都是正常的。 - thomas
API仍处于草稿阶段,不同浏览器之间的实现存在差异,所以我想这可能是原因。我能建议的就是尝试在另一台设备上测试它。您也可以尝试使用此库:https://github.com/richtr/Full-Tilt,看看是否有帮助。 - end3r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接