Question

At the moment I'm using the dot product of the mouse position and (0, 1) to generate radians to rotate an object, in three.js

Code below, works ok but the object 'jumps' because the radian angle skips from positive to negative when the clientX value goes between window.innerWidth / 2

onDocumentMouseMove : function(event) {
    // rotate circle relative to current mouse pos

    var oldPos = new THREE.Vector2(0, 1);


    Template.Main.mouseCurrPos = new THREE.Vector2((event.clientX / window.innerWidth ) * 2 - 1, - (event.clientY / window.innerHeight) * 2 + 1);


    Template.Main.mouseCurrPos.normalize();
    //Template.Main.projector.unprojectVector(Template.Main.mouseCurrPos, Template.Main.scene);

    var angle = oldPos.dot(Template.Main.mouseCurrPos);
    Template.Main.mousePrevPos.x = event.clientX;
    Template.Main.mousePrevPos.y = event.clientY;


    if (event.clientX < window.innerWidth / 2) {
        Template.Main.circle.rotation.z = -angle;
    }
    else {
        Template.Main.circle.rotation.z = angle;
    }

    console.log(Template.Main.circle.rotation.z);
}

However if I add this to assign the value to oldPos:

    if (event.clientX < window.innerWidth / 2) {
        oldPos = new THREE.Vector2(0, -1);
    }
    else {
        oldPos = new THREE.Vector2(0, 1);
    }

Then the "jumping" goes but the effect of rotation is inverted when the mouse is on the left of the window.

I.e. mouse going up rotates anti-clockwise and vice-versa which is not desired.

It's frustrating.

Also if I keep the oldPos conditional assignment and leave out the conditional negation of the angle instead, the jumping comes back.

You can see a demo here: http://theworldmoves.me/rotation-demo/

Many thanks for any tips.

Was it helpful?

Solution

Why are you using the result of the dot product as the angle (radians)? The dot product gives you the cosine of the angle (times the magnitude of the vectors, but these are a unit vector and a normalized vector, so that doesn't matter).

You could change your angle computation to

var angle = Math.acos(oldPos.dot(Template.Main.mouseCurrPos));

However, you may get the wrong quadrant, since there can be two values of theta that satisfy cos(theta) = n. The usual way to get the angle of a vector (origin to mouse position) in the right quadrant is to use atan2():

var angle = Math.atan2(Template.Main.mouseCurrPos.y,
                       Template.Main.mouseCurrPos.x);

This should give the angle of the mouse position vector, going counterclockwise from (1, 0). A little experimentation can determine for sure where the zero angle is, and which direction is positive rotation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top