这个矩阵值将转换为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调用并不便宜.因此,你应该避免使用太多的点
>在您的情况下,所有信号彼此接近,尤其是在使用高传感器频率时.你必须注意非常小的角度让1 / sin(ω)爆炸.在这种情况下,设置sin(x)≈x
>像low-pass filter等其他过滤器一样,您使用的时间越长,您获得的延迟时间就越长.因此,如果你有频率f,当使用两个点时,你将获得大约0.5 / f秒的延迟,而对于双重slerp,你将获得1.5 / f.
>如果某些内容看起来很奇怪,请检查生成的四元数是否为单位四元数,即|| q || = 1
>如果您遇到性能问题,可以查看Hacking Quaternions
github上的C项目pbrt包含一个四元数类,可以从中获得灵感.
总结以上是内存溢出为你收集整理的objective-c – 如何使用CADisplayLink在CMRotationMatrix上应用过滤器全部内容,希望文章能够帮你解决objective-c – 如何使用CADisplayLink在CMRotationMatrix上应用过滤器所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)