objective-c – 如何使用CADisplayLink在CMRotationMatrix上应用
如何在CMRotationMatrix上应用过滤器?也许卡尔曼过滤器.我需要修复CMRotationMatrix(transformFromCMRotationMatrix)的噪声,得到结果矩阵的线性值
这个矩阵值将转换为XYZ,在我的情况下,我在2D屏幕上模拟3D,如下所示: //将矩阵转换为x,y vec4f_t v; multiplyMatrixAndVector(v,projectionCameraTransform,boxMatrix); float x = (v[0] / v[3] + 1.0f) * 0.5f; float y = (v[1] / v[3] + 1.0f) * 0.5f; CGPointMake(x * self.bounds.size.width,self.bounds.size.height - (y * self.bounds.size.height)); 码: //定义变量 mat4f_t cameraTransform; //启动显示链接循环 - (void)startDisplayLink { displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onDisplayLink:)]; [displayLink setFrameInterval:1]; [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } //停止显示链接循环 - (void)stopDisplayLink { [displayLink invalidate]; displayLink = nil; } //显示链接的事件 - (void)onDisplayLink:(id)sender { CMDeviceMotion *d = motionManager.deviceMotion; if (d != nil) { CMRotationMatrix r = d.attitude.rotationMatrix; transformFromCMRotationMatrix(cameraTransform,&r); [self setNeedsDisplay]; } } // [self setNeedDisplay]之前的函数触发器; void transformFromCMRotationMatrix(vec4f_t mout,const CMRotationMatrix *m) { mout[0] = (float)m->m11; mout[1] = (float)m->m21; mout[2] = (float)m->m31; mout[3] = 0.0f; mout[4] = (float)m->m12; mout[5] = (float)m->m22; mout[6] = (float)m->m32; mout[7] = 0.0f; mout[8] = (float)m->m13; mout[9] = (float)m->m23; mout[10] = (float)m->m33; mout[11] = 0.0f; mout[12] = 0.0f; mout[13] = 0.0f; mout[14] = 0.0f; mout[15] = 1.0f; } // Matrix-vector和matrix-matricx乘法例程 void multiplyMatrixAndVector(vec4f_t vout,const mat4f_t m,const vec4f_t v) { vout[0] = m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3]; vout[1] = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3]; vout[2] = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3]; vout[3] = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3]; } 解决方法
一般来说,我会区分提高信噪比和消除信号.
信号改善 如果您真的想要比已经实施传感器融合算法的Apple的Core Motion更好,请为具有不确定结果的长期项目做好准备.在这种情况下,您最好采用原始加速度计和陀螺仪信号来构建您自己的传感器融合算法,但您必须关注许多问题,如漂移,不同iPhone版本的硬件依赖性,传感器内的硬件差异一代,…所以我的建议:尽量避免它. 平滑 这只是意味着插入两个或更多信号并构建平均值.我不知道任何合适的方法直接用于旋转矩阵(可能有一个)但你可以使用quaternions(更多资源:OpenGL Tutorial Using Quaternions to represent rotation或Quaternion FAQ). 这种插值的结果四元数可以与矢量相乘以获得与矩阵方式类似的投影(有关更多信息,请查看Finding normal vector to iOS device). 表示旋转的两个单位四元数之间的插值可以通过Slerp完成.实际上,您将使用维基百科中描述为Geometric Slerp的内容.如果你有两个时间点t1和t2以及相应的四元数q1和q2以及它们之间的角距离omega,则公式为: q'(q1,q2,t)= sin((1-t)* omega)/ sin(ω)* q0 sin(t * omega)/ sin(ω)* q1 t应为0.5,因为您需要两次旋转之间的平均值.欧米茄可以通过点积计算: cos(ω)= q1.q2 = w1 * w2 x1 * x2 y1 * y2 z1 * z2 如果使用两个四元数的方法仍然不符合您的需要,可以使用slerp(slerp(q1,q2),slerp(q3,q4))重复此操作.一些说明: >从性能的角度来看,在你的运行循环1 /频率时间每秒执行三次sin和一次arccos调用并不便宜.因此,你应该避免使用太多的点 github上的C项目pbrt包含一个四元数类,可以从中获得灵感. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |