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

Math 使用四元数创建第三人称摄影机位置计算,math,rotation,webgl,three.js,quaternions,Math,Rotation,Webgl,Three.js,Quaternions,我想创建一个类似的第三人称相机。如果摄影机和对象之间的旋转差太大(可能超过10%),则摄影机应保持在对象后面并旋转 这是我的实际相机代码: var targetPosition = this.getTargetPosition(); var targetRotation = this.getTargetRotation(); var tmpQuaternion = new THREE.Quaternion(); tmpQuaternion.setFromAxisAngle(new THREE.V

我想创建一个类似的第三人称相机。如果摄影机和对象之间的旋转差太大(可能超过10%),则摄影机应保持在对象后面并旋转

这是我的实际相机代码:

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示例:

更新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;
};
但是我知道如果角度差太大,我需要冻结轴。我该怎么做


如果您有任何帮助,我们将不胜感激。

好的。最后,摄像机已安装完毕,可以正常工作,但以下情况除外:

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();