记录一个iOS使用陀螺仪3d效果的抖动问题

2023-11-06

使用陀螺仪的时候,遇到一个问题,就是在拖动scrollView滚动的时候,3d效果的图片会抖动

实现3d效果的代码

- (void)updateWithGravityX:(double)gravityX
                  gravityY:(double)gravityY
                  gravityZ:(double)gravityZ
{
    //因为在斜向上45度角的时候,gravity的值是-0.5,设计要求以这个位置为基准,所以要减去-0.5
    gravityY -= (-0.5);
    gravityY *= 2;
    //最大的便宜量是maxoffset,所以gravityY最大为1
    gravityY = MIN(1, MAX(-1, gravityY));
    
    gravityX *= 2;
    gravityX = MIN(1, MAX(-1, gravityX));
    
    double timeInterval = sqrt(pow((gravityX - lastGravigyX),2) + pow((gravityY - lastGravityY), 2)) * deviceMotionUpdateInterval;
    NSString *animationKey = @"positionAnimation";
    CGPoint newBackImageViewCenter = self.backImageView.center;
    newBackImageViewCenter.x = (newBackImageViewCenter.x - gravityX * maxOffset);
    newBackImageViewCenter.y = (newBackImageViewCenter.y + gravityY * maxOffset);
    
    CABasicAnimation *backImageViewAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    backImageViewAnimation.fromValue = [NSValue valueWithCGPoint:backImageViewCenter];
    backImageViewAnimation.toValue = [NSValue valueWithCGPoint:newBackImageViewCenter];
    backImageViewAnimation.duration = timeInterval;
    backImageViewAnimation.fillMode = kCAFillModeForwards;
    backImageViewAnimation.removedOnCompletion = NO;
    
    [self.backImageView.layer removeAnimationForKey:animationKey];
    [self.backImageView.layer addAnimation:backImageViewAnimation forKey:animationKey];
    
    CGPoint newFrontImageViewCenter = self.frontImageView.center;
    newFrontImageViewCenter.x += gravityX * maxOffset;
    newFrontImageViewCenter.y -= gravityY * maxOffset;
    
    CABasicAnimation *frontImageViewAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    frontImageViewAnimation.fromValue = [NSValue valueWithCGPoint:frontImageViewCenter];
    frontImageViewAnimation.toValue = [NSValue valueWithCGPoint:newFrontImageViewCenter];
    frontImageViewAnimation.duration = timeInterval;
    frontImageViewAnimation.fillMode = kCAFillModeForwards;
    frontImageViewAnimation.removedOnCompletion = NO;
    [self.frontImageView.layer removeAnimationForKey:animationKey];
    [self.frontImageView.layer addAnimation:frontImageViewAnimation forKey:animationKey];
    
    CGPoint newSecondFrontImageViewCenter = self.smallMovementView.center;
    if (self.smallMovementView == self.secondFrontImageView) {
        newSecondFrontImageViewCenter.x += gravityX * maxOffset/3;
        newSecondFrontImageViewCenter.y -= gravityY * maxOffset/3;
    } else if (self.smallMovementView == self.middleImageView) {
        newSecondFrontImageViewCenter.x -= gravityX * maxOffset/3;
        newSecondFrontImageViewCenter.y += gravityY * maxOffset/3;
    }

    CABasicAnimation *secondfrontImageViewAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    secondfrontImageViewAnimation.fromValue = [NSValue valueWithCGPoint:secondFrontImageViewCenter];
    secondfrontImageViewAnimation.toValue = [NSValue valueWithCGPoint:newSecondFrontImageViewCenter];
    secondfrontImageViewAnimation.duration = timeInterval;
    secondfrontImageViewAnimation.fillMode = kCAFillModeForwards;
    secondfrontImageViewAnimation.removedOnCompletion = NO;
    [self.smallMovementView.layer removeAnimationForKey:animationKey];
    [self.smallMovementView.layer addAnimation:secondfrontImageViewAnimation forKey:animationKey];
    
    backImageViewCenter = newBackImageViewCenter;
    frontImageViewCenter = newFrontImageViewCenter;
    secondFrontImageViewCenter = newSecondFrontImageViewCenter;
}

由 以上代码可以知道,我们的图片抖动就是图片的位置突变造成的,
而我们scrollview滚动的时候有突变,不滚动的时候没有突变。
我们打印位置的变化,发现打印太频繁,就修改了时间1/40 为 1 ,
发现我们我们如果不拖动,执行的位置改变没有突变的。但是时候
打印仍然比较频繁,我就讲时间改为10 ,这时候发现了一个问题,
就是不管我们拖动不拖动,每次改变的大小都很大超过了16,
发现如下想象
请添加图片描述

由此可以推断,是我们设置的陀螺仪更新频率不够大,导致
我们移动了很大距离之后,才更新位置,导致发生了突变现象,
而更新位置就是在陀螺仪的回调方法中实现的,就是说,我们
移动了很大的位置,陀螺仪才进行了回调,这才导致抖动。
如果陀螺仪的回调很频繁,那么我们移动了很小的距离,陀螺仪就会
回调,这个时候就不会有抖动的效果。
由此可以想到修改陀螺仪的时间
由于最新的苹果手机更新频率是120hz,
所以这里设置成了1/120

    deviceMotionUpdateInterval = 1 / 120.0;

- (CMMotionManager *)motionManager
{
    if (!_motionManager) {
        _motionManager = [[CMMotionManager alloc] init];
        _motionManager.deviceMotionUpdateInterval = deviceMotionUpdateInterval;
    }
    return _motionManager;
}

由此我们还可以得出一个结论,如果我们发现了抖动显现,
就可以推推测有可能 是位置发生了突变

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

记录一个iOS使用陀螺仪3d效果的抖动问题 的相关文章

随机推荐

  • 通过 jd-gui 查看 jeeSite 的framework

    最近有一个单体应用开发 综合比对下选择了jeeSite 前端虽有瑕疵 后台功能确实做的不错 一切准备就绪 环境搭建好了 准备开发 需要修改角色信息 发现代码当中竟然没有 后来查看了下maven仓库下的jeesite framework 4
  • Qt信号与槽传递自定义数据类型

    Qt信号与槽之间传递typedef定义的数据类型或其他类型 在编译时不报错 但在执行时会报如下错误 QObject connect Cannot queue arguments of type elemType Make sure elem
  • R语言报错记录The following objects are masked from ‘package:stats’:decompose, spectrum

    报错记录 大家好 这里是想做生信大恐龙 的生信小白 这是一条简短的报错记录 参考了其他博主的方法 如有侵权 请联系删除 报错记录 报错记录 报错原因 解决方法 总结 报错原因 使用R语言第三方包 igraph 时出现了以下报错 The fo
  • 【Qt教程】3.5 - Qt5 QPainter绘图抗锯齿、相对坐标/平移坐标系、QPainter画图片、手动调用QPainter绘图事件

    GitHub源码仓库 Qt学习例程 1 QPainter绘图抗锯齿 抗锯齿测试 painter drawEllipse QPoint 100 50 50 50 设置 抗锯齿能力 抗锯齿会让绘图效率较低 painter setRenderHi
  • CVPR 2021

    双图层实例分割 物体的互相遮挡在日常生活中普遍存在 严重的遮挡易带来易混淆的遮挡边界及非连续自然的物体形状 从而导致当前已有的检测及分割等的算法性能大幅下降 本文通过将图像建模为两个重叠图层 为网络引入物体间的遮挡与被遮挡关系 从而提出了一
  • pip install PIL 报错

    使用 pip install PIL 时报如下错误 Collecting PIL Could not find a version that satisfies the requirement PIL from versions No ma
  • kubernetes常用命令汇总

    1 查询命名空间 kubectl get ns 2 查询服务名 kubectl get po 3 查询对应命名空间下的服务名 kubectl n namespace get po 4 根据命名空间下某个服务的查询日志 kubectl n n
  • Git1 基础

    1 什么是git 1 1 简介 GIT是一种分布式版本控制系统 通俗点说版本控制就是当文档写错了 能够让你回退到之前某个正确的版本 给你一着悔棋 1 2 版本控制系统 1 2 1 本地版本控制系统 许多人习惯用复制整个项目目录的方式来保存不
  • 服务器虚拟化优缺点

    将服务器物理资源抽象成逻辑资源 让一台服务器变成几台甚至上百台相互隔离的虚拟服务器 我们不再受限于物理上的界限 而是让CPU 内存 磁盘 I O等硬件变成可以动态管理的 资源池 从而提高资源的利用率 简化系统管理 实现服务器整合 让IT对业
  • java语言特点和跨平台原理

    Java语言 1 java的三大版本 JavaSE J2SE java的标准版本定位在客户端 主要用于桌面应用软件的编程 JavaEE 定位在服务器端java2的企业版 主要用于分布式网络程序的开发 如电子商务网站 JavaME J2ME主
  • 实验:使用SSMS创建并管理数据库及其基本表

    目录 题目要求 1 创建数据库 2 创建三个表 3 修改限制条件 4 创建及管理约束条件 5 录入基本数据 6 数据的更改和插入 7 分离与附加数据库 题目要求 实验课程 数据库系统原理 专业 计算机科学与技术 班级 实验日期 姓名 学号
  • Qt信号与槽的各种连接方式

    信号槽是 Qt 框架引以为豪的机制之一 当用户触发某个事件时 就会发出一个信号 signal 这种发出是没有目的的 类似广播 如果有对象对这个信号感兴趣 它就会连接 connect 绑定一个函数 称为槽slot 来处理这个信号 也就是说当信
  • sklearn库简述-zstarling

    文章目录 模型的选择与评估 划分数据集 评估模型 监督学习 最近邻 支持向量机 SVM 决策树 集成方法 朴素贝叶斯 线性回归 随机梯度下降 判别分析 模型的选择与评估 划分数据集 from sklearn model selection
  • 如何更改linux文件的拥有者及用户组(chown和chgrp)

    本文整理自 http blog 163 com yanenshun 126 blog static 128388169201203011157308 http ydlmlh iteye com blog 1435157 一 基本知识 在Li
  • [C/C++] undefined reference to ‘std::cout‘

    gcc TrackersManger cpp o TrackersManger 编译时出现如下错误 原因是 编译 cpp 文件时 需要使用 g 编译 改为如下即可 g TrackersManger cpp o TrackersManger
  • 国产操作系统迎来最好时代

    在国家强力政策推动及下游需求快速提升的双重作用下 网络安全和自主可控领域正在迎来行业大爆发 能够充分防范 永恒之蓝 等外来病毒侵袭 各方面日臻成熟的国产操作系统的最好时代已经渐行渐近 不久前 基于 永恒之蓝 攻击模块衍生出的 想哭 勒索病毒
  • 在linux上替换动态库的内存变化分析

    在linux上替换动态库的内存变化 测试static变量 static string staticString 123 void queryFreezingMoney CFmlBuf inBuf CFmlBuf outBuf string
  • 使用chatGPT辅助编写测试用例

    目录 一 问答1 0版 二 问答2 0版 2 1 问答2 1 2 2 问答2 2 2 3 问答2 3 三 问答3 0版本 四 思考 个人简介 作者简介 大家好 我是凝小飞 软件测试领域作者 支持我 点赞 收藏 留言 最近开始学习和写作 请大
  • 前端基础(一):Jquery

    1 dom和jquery的互相转化 2 选择器 3 过滤器 4 DOM操作 1 dom和jquery的互相转化 dom转jquery dom对象 jquery转dom 方法一 a 0 方法二 a get 0 2 选择器 1 基本选择器 id
  • 记录一个iOS使用陀螺仪3d效果的抖动问题

    使用陀螺仪的时候 遇到一个问题 就是在拖动scrollView滚动的时候 3d效果的图片会抖动 实现3d效果的代码 void updateWithGravityX double gravityX gravityY double gravit