使用四元数创建第三人称相机位置计算

Posted

技术标签:

【中文标题】使用四元数创建第三人称相机位置计算【英文标题】:Create 3rd person camera position calculation with quaternions 【发布时间】:2012-07-07 20:29:12 【问题描述】:

我想创建一个类似于example 的第三人称相机。如果相机和物体之间的旋转差异太大(可能超过百分之十),相机应该贴在物体后面并旋转。

这是我的实际相机代码:

var targetPosition = this.getTargetPosition();
var targetRotation = this.getTargetRotation();
var tmpQuaternion = new THREE.Quaternion();
tmpQuaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), 180 * (Math['PI'] / 180));
this.camera.quaternion = targetRotation;
this.camera.position = targetPosition;
this.camera.quaternion.multiplySelf(tmpQuaternion);
this.camera.quaternion.normalize();
this.camera.updateMatrix();
this.camera.translateZ(200);
this.camera.translateY(50);

但是现在有几个问题。相机四元数不应直接设置为目标旋转。但我不知道如何计算相机四元数和目标四元数之间的差异,如果距离太高,可能会使用这个:

var qm = new THREE.Quaternion();
THREE.Quaternion.slerp(targetRotation, this.camera.quaternion, qm, time);
this.camera.quaternion = qm;

第二个问题是职位本身。目前我将相机位置设置为对象位置并将其转换回后面的视图,但平移应该已经在目标位置并且相机位置应该转换到目标位置。

更新1:我做了一个例子html:http://ssachtleben.github.com/CameraProblem/

更新 2:我现在取得了一些进展。好像我用这个函数得到了四元数的区别:

getAxisAngle = function(quaternion1, quaternion2) 
  var tmpQuaternion = new THREE.Quaternion();
  tmpQuaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), 180 * (Math['PI'] / 180));
  var tmpRotation1 = quaternion1.clone();
  tmpRotation1.multiplySelf(tmpQuaternion);
  tmpRotation1.normalize();
  var tmpRotation2 = quaternion2.clone();
  if (tmpRotation2.w > 1) 
    tmpRotation2.normalize();
  
  var angle1 = 2 * Math['acos'](tmpRotation1.w);
  var angle2 = 2 * Math['acos'](tmpRotation2.w);
  var diff = angle1 > angle2 ? angle1 - angle2 : angle2 - angle1;
  return diff;
;

但是如果角度差太大,我需要冻结轴。我该怎么做?

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

好的,相机终于修好了,可以正常工作了:

var targetPosition = this.getTargetPosition();
var targetRotation = this.getTargetRotation();
var tmpQuaternion = new THREE.Quaternion();

tmpQuaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), 180 * (Math['PI'] / 180));
targetRotation.multiplySelf(tmpQuaternion);
targetRotation.quaternion.normalize();

var qm = new THREE.Quaternion();
THREE.Quaternion.slerp(this.camera.quaternion, targetRotation, qm, 0.07);
this.camera.quaternion = qm;
this.camera.quaternion.normalize();

【讨论】:

以上是关于使用四元数创建第三人称相机位置计算的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地使用四元数进行旋转

限制相机间距

将四元数旋转转换为旋转矩阵?

计算四元数逆

四元数法

使用四元数计算 iphone 的偏航、俯仰和滚动?