介绍大家有没有注意到,近年来,我们看到越来越少的演讲者在演讲中使用激光笔向听众指示他们在说什么。先说激光笔。激光笔的工作原理是发射一束激光,照射在屏幕上,反射到观众的眼睛里,让每个人都能看到一个非常明亮的红色光点。但是现在因为大尺寸屏幕越来越便宜,我们越来越少使用幕布等传统投影显示设备。毕竟屏幕的显示效果更好。为了保证良好的显示效果,屏幕往往会在表面的玻璃上采用大量的增透技术。这些抗反射技术的使用极大地削弱了激光的反射,因此最终用户看到的红色光点不那么显眼,激光笔的效果也大大降低。那么是不是可以用大家出门时唯一愿意携带的手机来代替激光笔呢?我尝试了以下两个选项。3D模拟方案简单来说就是利用手机内置的姿态传感器和加速度传感器,在三维空间中构建手机和显示器的方位和姿态,然后模拟计算如果一束光激光从手机发出,会照在屏幕上手机所在的位置,并在屏幕相应位置画一个红点,从而实现手机模拟激光的效果指针。如上图所示,假设屏幕的相邻两条边分别平行于X轴和Z轴。当手机沿着屏幕的一侧从A点移动到B点,再沿着屏幕的另一侧从B点移动到C点时,我们就可以计算出屏幕在三维空间中的具体位置以A点为原点。地点。计算方法其实很简单。比如我们在计算从A到B的过程时,只需要利用手机上的加速度传感器,取出手机一直在x轴方向的加速度,然后乘以时间即可得到时间刻在x轴方向的速度,速度乘以时间就可以得到手机在x轴方向移动了多少。简单的说就是在时间维度上对手机在x轴方向的加速度进行两次积分。可以通过将手机从A点移动到B点和C点来计算屏幕的位置。自然也可以随时计算出手机相对于屏幕的空间位置和姿态方向,模拟手机发射激光束的计算。屏幕上的哪个位置将被照亮。但是,经过实验,我发现这个方案虽然理论上可行,但由于误差累积的存在,实际上是不可行的。我们以手机从A点移动到B点这个最基本的场景为例。当一个人拿着手机从A点移动到B点时,手机的加速度、速度和移动距离可以用下面三张图来描述。横轴t代表时间,纵轴a、v、d分别代表手机在x方向的加速度、速度和移动距离。第一张图中,加速度前半部分为正,后半部分为负,所以手机在x方向先加速后减速,速度从0增加到最大,然后慢慢减小到0,而移动距离开始因为速度比较慢,所以增长缓慢。中间速度达到最大值,移动距离也增加最快。最终速度归零,移动距离不再增加。但问题在于加速度。本来,加速度正数部分的积分和负数部分的积分,也就是蓝色区域的面积和黄色区域的面积是完全一样的,所以速度运动过程结束手机会归0,但实际情况并非如此。首先,现实世界中的物理量是连续的,加速度当然也是连续的。但是通过手机操作系统提供的各种接口获取的加速度不可能是连续的,只能每16ms获取一个值。因此,在计算蓝色和黄色区域的面积时,只能通过计算几个矩形的面积,然后相加得到一个近似值。其次,手机操作系统通过接口提供的加速和真正的加速肯定是有区别的。任何测量都有误差。只有真实的值才会使蓝色和黄色区域的面积完全相同。所以,由于以上两个原因,手机从A点移动到B点后,我们测量加速度,计算速度,最后发现手机到达B点后,速度还没有归零,并且速度还没有回到0,这意味着系统认为手机还在沿x轴匀速移动,最终导致整个系统无法使用。3D仿真方案的根本问题是我们需要对有误差的量进行时间积分。我们都知道错误并不可怕。几乎所有的测量量都有误差。更可怕的是累积误差,它会让你的系统在运行一段时间后完全失控,而3D仿真方案更糟糕的是,这个误差是在时间维度上累积的,并且时间不会停止。在3D仿真方案中姿态仿真方案失败后,想到了简化版的方案。既然误差不能用加速度,那可不可以考虑简单点,只用没有累积误差的方向传感器来实现控制呢?假设手机初始位置正对屏幕中心,只要知道手机到屏幕的距离和手机绕x轴旋转的角度β,就可以计算出远处红灯会向上移动。但是我们没有距离传感器,前面说了不能用加速度来计算距离,那我们再简化一下,不考虑距离,只考虑角度。我们认为手机的初始位置设置为屏幕中心。当x轴向上旋转25度时,红点将从屏幕中心移动到屏幕顶部。当x轴向下旋转25度时,红点将移动到屏幕底部。当手机绕z轴左右旋转25度时,红点分别移动到屏幕的最左边和最右边。这样,我们只用一个简单的姿态传感器就可以达到模拟激光笔的效果。实验证明该方案完全可行,代码逻辑简单。当然这个方法是假设了手机的初始姿势,实际上是假设了手机到屏幕的距离(你可以想想为什么手机到屏幕的距离也被假设了^\_^),用户在使用时可能会有一点感觉。有点不自然。同时,为了拥有更好更便捷的操控体验,还需要增加一些让用户重新设置手机姿势的功能。Demo本文提到的姿势模拟方案可以在LaserPenDemo中体验,相关代码在LaserPen-Github的示例目录中。在pc浏览器中打开演示页面后等待几秒钟,您应该会在页面的标题中看到生成的二维码。当手机控制页面显示“已连接”时,可以尝试挥动手机控制pc页面的小红点。关于这个演示还有两个注意事项。首先,demo中获取的手机姿态数据是通过WebRTC技术直接发送到PC页面的,不用担心个人敏感信息泄露。其次,虽然该demo的主要通信方式是WebRTC,但是建立WebRTC链接的过程需要一些消息推送的手段,所以该demo也使用了socket.io。最后,该演示使用了一个免费的后端服务,该服务已经有一段时间无法使用了。一个人来访后会自动停止,下次来访还要等将近两分钟才能开始服务。所以如果打开PC页面发现二维码没有显示,可以先喝杯水,然后回来刷新页面试试。最后,欢迎大家star、pr、issue我的项目LaserPen-Github欢迎大家关注我的公众号:Tiger'sNest
