Ответ буквально пришел ко мне во сне, смеется.
Неожиданным поведением было то, что сила в отрицательном направлении у была отрицательной, когда она должна была быть положительной, вызывая увеличение результирующей скорости.абсолютное значение.
Конечно, добавив проверку, чтобы убедиться, что у-компонент силы всегда имел противоположный знак у-компонента данной скорости, решил проблему.
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)
Подумав немного, я понял, что, поскольку asin
и acos
являютсяв обратном порядке к sin
и cos
, соответственно, код можно уменьшить, чтобы полностью исключить использование sin
и cos
.
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)
}
}
}