ios - 自定义 UIFieldBehavior 中的意外加速

标签 ios swift uikit physics uikit-dynamics

我正在创建一个自定义字段,以在用户执行平移手势后减慢对象的运动速度。使用正常的摩擦力会使物体感觉太滑,因此我尝试应用 Spring 物理来代替摩擦力。

我有一个函数似乎可以正确计算我正在寻找的行为。

extension UIFieldBehavior {
    static func dampingField(_ constant: CGFloat) -> UIFieldBehavior {
        return UIFieldBehavior.field { field, position, velocity, mass, charge, time in
            let speed = sqrt(pow(velocity.dx, 2) + pow(velocity.dy, 2))
            let angle = acos(velocity.dx / speed)
            let force = -constant * speed
            guard angle.isNaN == false, force.isNaN == false
                else { return .zero }
            return  CGVector(dx: cos(angle) * force, dy: sin(angle) * force)
        }
    }
}

但是,垂直运动的表现并不符合我的预期。任何朝向引用 View 顶部的运动都会导致对象加速得更快。

我玩三角学有一段时间了,但我很困惑。有an example swift playground在 GitHub 上演示了这个问题。

我在数学中忽略了什么?

最佳答案

答案确实是在梦中出现的,哈哈。

意想不到的行为是负 y 方向上的力本应为正,但却变成了负,导致最终速度的绝对值增加。

果然,添加检查以确保力的 y 分量始终具有与给定速度的 y 分量相反的符号解决了问题。

var vector = CGVector(dx: cos(angle) * force, dy: sin(angle) * force)
if vector.dy.sign == velocity.dy.sign {
    vector.dy *= -1
}
return vector

试图思考为什么只有 y 分量被错误地签名,我注意到角度是相对于 x 轴计算的。

let angle = acos(velocity.dx / speed)

我想我应该尝试根据相对于 y 轴的角度来计算 y 坐标的力,这也解决了问题。

return CGVector(dx: cos(angle) * force, dy: sin(asin(velocity.dy / speed)) * force)

思考了一下,我意识到,因为 asinacossincos 分别,可以减少代码以完全删除 sincos 的使用。

return CGVector(dx: velocity.dx / speed * force, dy: velocity.dy / speed * force)

实际上,我根本不需要将三角学引入其中,因为对向量分量的操作相当于对向量本身的操作。现在我的力量按预期工作并且更容易推理。

extension UIFieldBehavior {
    static func dampingField(_ constant: CGFloat) -> UIFieldBehavior {
        return UIFieldBehavior.field { field, position, velocity, mass, charge, time in
            return  CGVector(dx: -constant * velocity.dx, dy: -constant * velocity.dy)
        }
    }
}

关于ios - 自定义 UIFieldBehavior 中的意外加速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50439223/

相关文章:

ios - 如何检测iOS中的封闭区域并在其中填充颜色?

objective-c - 如何让这张图片显示在我的电子邮件正文中?

ios - Swift 字典已填满但仍为空

ios - 无法更改标题导航 Controller

ios - 当加载WKWebview时,它是nil

iphone - 查找 UIKit 元素子类化的文档

ios - 如何选择合适的 UIGestureRecognizer?

ios - 隐藏状态栏 iOS

ios - 渐进式加载 subview 以加快 iOS 应用程序性能

ios - UIPageViewController:如何在页面顶部显示 UIPageControl