【发布时间】:2018-02-19 18:23:33
【问题描述】:
我有两个四元数:
SCNVector4(x: -0.554488897, y: -0.602368534, z: 0.57419008, w: 2.0878818)
SCNVector4(x: 0.55016619, y: 0.604441643, z: -0.576166153, w: 4.18851328)
如果我们创建两个对象,方向将非常相似
但是如果我们尝试从第一个到第二个 Lerp,那么位置会发生非常奇怪的变化(并且查看预期但不正确的值)
[Lerp 进度演示][1]
我在谷歌上搜索并发现了许多功能来做 lerp,例如简单的一个:
extension SCNVector4 {
func lerp(to: SCNVector4, v: Float) -> SCNVector4 {
let aX = x + (to.x - x) * v
let aY = y + (to.y - y) * v
let aZ = z + (to.z - z) * v
let aW = w + (to.w - w) * v
return SCNVector4Make(aX, aY, aZ, aW)
}
}
但是如何避免这种奇怪的翻转呢?
PS:我尝试了 GLKit 的不同功能,但结果是一样的 [1]:https://i.stack.imgur.com/8jEvm.png
- 正如建议的那样尝试翻转符号,但问题是我得到的点积大于 0
extension SCNVector4 {
func glk() -> GLKQuaternion {
return GLKQuaternion(q: (x, y, z, w))
}
func lerp(to: SCNVector4, v: Float) -> SCNVector4 {
let a = GLKQuaternionNormalize(glk())
let b = GLKQuaternionNormalize(to.glk())
let dot =
a.x * b.x +
a.y * b.y +
a.z * b.z +
a.w * b.w
var target = b
if dot < 0 {
target = GLKQuaternionInvert(b)
}
let norm = GLKQuaternionNormalize(GLKQuaternionSlerp(a, target, v))
return norm.scn()
}
}
extension GLKQuaternion {
func scn() -> SCNVector4 {
return SCNVector4Make(x, y, z, w)
}
}
【问题讨论】:
标签: scenekit quaternions lerp