我正在使用雙指觸摸事件來使用四元數捏 - 旋轉 - 縮放一個對象THREE.Mesh
。這是我第一次使用這種旋轉方法,並且由於我確定了一些我似乎無法理解的四元數屬性,當總觸摸阻力將對象旋轉大約90度時,旋轉逐漸開始在整個地方抖動°。然後,當再次拖回到90°以下時,它會逐漸恢復到原始平滑,儘管明顯呈非線性旋轉。 (90°只是一個猜測)。四分位數旋轉在three.js旋轉超過約90°時會走路
我完全難住了。下面是我使用旋轉對象obj
代碼:
// global state
var
// keeps track of original object scale
pinchScale = new THREE.Vector3(),
// current first touch
touch1 = new THREE.Vector2(),
// current second touch
touch2 = new THREE.Vector2(),
// first touch at touch start
touch1OnHold = new THREE.Vector2(),
// second touch at touch start
touch2OnHold = new THREE.Vector2(),
// keeps track of total held rotation at last fired touchmove event
angularHoldPrev = new THREE.Quaternion();
⋮
// key-value pairs inside an addEventListener utility
touchstart: function (event) {
event.preventDefault();
if (event.touches.length === 1) {
…
} else if (event.touches.length === 2) {
touch1OnHold.set(event.touches[0].pageX, event.touches[0].pageY);
touch2OnHold.set(event.touches[1].pageX, event.touches[1].pageY);
angularHoldPrev.set(0, 0, 0, 1)
}
},
touchmove: function (event) {
event.preventDefault();
if (event.touches.length === 1) {
…
} else if (event.touches.length === 2) {
touch1.set(event.touches[0].pageX, event.touches[0].pageY);
touch2.set(event.touches[1].pageX, event.touches[1].pageY);
var
// get touch spread at present event firing, and at the start of current hold
touchDiff = touch2.clone().sub(touch1),
touchDiffOnHold = touch2OnHold.clone().sub(touch1OnHold),
// camera is on z-axis; get this axis regardless of obj orientation
axis1 = new THREE.Vector3(0, 0, 1).applyQuaternion(obj.quaternion.clone().inverse()),
// get a touch rotation around this axis
rot1 = new THREE.Quaternion().setFromAxisAngle(axis1, (Math.atan2(touchDiffOnHold.y, touchDiffOnHold.x) - Math.atan2(touchDiff.y, touchDiff.x))).normalize(),
// get touch barycentre at present event firing, and at the start of current hold
touchCentre = touch1.clone().add(touch2).multiplyScalar(.5),
touchCentreOnHold = touch1OnHold.clone().add(touch2OnHold).multiplyScalar(.5),
// get axis of touch barycentre movement on the xy plane, regardless of obj orientation
axis2 = new THREE.Vector3(touchCentre.y - touchCentreOnHold.y, touchCentre.x - touchCentreOnHold.x, 0).applyQuaternion(obj.quaternion.clone().inverse()),
// get a rotation proportional to magnitude of touch movement
rot2 = new THREE.Quaternion().setFromAxisAngle(axis2, axis2.length() * rotationSensitivity).normalize(),
// combine the two rotations
rot = rot1.multiply(rot2);
// undo last rotation if not the empty quaternion
if (!angularHoldPrev.equals(new THREE.Quaternion())) obj.quaternion.multiply(angularHoldPrev.inverse());
// perform the currently calculated rotation
obj.quaternion.multiply(rot);
// save this rotation for next event firing
angularHoldPrev.copy(rot);
// resize object according to change in touch spread
obj.scale.copy(pinchScale.clone().multiplyScalar(touchDiff.length()/touchDiffOnHold.length()))
}
},
touchend: function (event) {
event.preventDefault();
// reset original object scale
pinchScale.copy(obj.scale)
}
任何線索我怎麼能維護所有雙觸摸輸入比例旋轉將不勝感激。乾杯。
快速猜測沒有深深看可能是你ATAN2。 tan函數以90度拉到無限遠處。 –
我很擔心。然而atan2沒有任何的無窮大,只有正面和負面180°之間的不連續性。 –