【问题标题】:continuos smooth incremental rotation of a node (camera)节点(相机)的连续平滑增量旋转
【发布时间】:2015-02-28 23:40:56
【问题描述】:

我正在尝试将相机绕 x 轴增量旋转 5 度。它工作正常,除了 355 处突然跳跃的动画。它是由于动画链接而发生的。如果在SCNSceneRendererDelegate 中调用了我的以下方法,则它不是基于时间的轮换。 SCNSceneRendererDelegate 在每一帧中被触发。这意味着我的带有持续时间的场景动画动作还没有准备好。通过降低动画持续时间,动画不再流畅。做一个基于与动画持续时间相同的间隔的计时器看起来也很糟糕。有没有办法让这个动画流畅?

-(void) updateCameraRotation
{
     SCNQuaternion oldRotScnQuat = _cameraNode.presentationNode.rotation;
     GLKQuaternion glQuatOldRot = GLKQuaternionMakeWithAngleAndAxis(oldRotScnQuat.w, oldRotScnQuat.x, oldRotScnQuat.y, oldRotScnQuat.z);

     float xan = GLKMathDegreesToRadians(5);
     GLKQuaternion newx = GLKQuaternionIdentity;
     GLKVector3 vec = GLKVector3Normalize(GLKVector3Make(1, 0, 0));
     double result = sinf(xan/2);
     newx = GLKQuaternionMakeWithAngleAndAxis(cosf(xan/2), vec.x *result, vec.y * result, vec.z * result);
     newx = GLKQuaternionNormalize(newx);
     glQuatOldRot = GLKQuaternionMultiply(glQuatOldRot, newx);

     axis = GLKQuaternionAxis(glQuatOldRot);
     angle = GLKQuaternionAngle(glQuatOldRot);


    [_cameraNode runAction:[SCNAction rotateToAxisAngle:SCNVector4Make(axis.x, axis.y, axis.z, angle) duration:1]];
}

【问题讨论】:

  • 在每一帧都调用委托方法是真的。但是“这意味着我的带有持续时间的场景动画动作还没有准备好”是什么意思?
  • 如果动画持续时间是例如 5 秒长,那么在这 5 秒内,代理每秒触发 60 个计时器。所以该方法在动画期间被调用了 300 次。它会旋转 300 x 5 度。所以那不好。我也尝试取消之前的动画,甚至删除了动作,但没有帮助。
  • 我觉得我的角度有问题。这是保持旋转的正确方法吗?
  • 如果您的代码以 60fps 运行,也许您不需要动画。或者您可以使用隐式动画而不是动作。使用隐式动画(参见SCNTransaction)会自动创建从当前值到新值的动画,无需取消之前的调用。
  • 60 fps 只是一个例子,例如在 ipad 2 上不会出现这种情况。轮换不是永远的。它由设备方向和/或虚拟操纵杆控制。如果用户在一个方向上持续按下按钮,它将旋转相机,否则它将是静止的。

标签: ios rotation quaternions scenekit


【解决方案1】:

SLERP 用于在两个已知姿态之间进行平滑旋转。尽量避免在轴角和四元数之间进行不必要的转换(如果可能,将它们留在四元数中)。 http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/

您还需要计算四元数轴之间的角度:https://math.stackexchange.com/questions/90081/quaternion-distance

这两个功能我自己都用过,效果很好。 您可以指定 [0, 1] 范围内的标量 t,而不是每帧添加 5 度。

例如,当从四元数 P 旋转到 Q 时,R = SLERP(P,Q,t) 将给出从 P 到 Q 的四元数 R。如果 t = 0,则 R = P,如果 t = 1,则 R =问。

【讨论】:

    【解决方案2】:

    尝试提供一个 CABasicAnimation 并将 byValue 设置为 5 度,并将重复设置为无限。那不行吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多