I'm working on a project in three.js where I have a cube and can rotate it with some buttons (arrows). The rotation works, but after some rotations it doesn't spin in the right direction anymore. Probably because the axes of the cube are shifted? But this confuses me a little bit..
I need the cube to be able to rotate up, down, left and right by some controls. This is basically how it currently works:
When a direction is pressed, say 'right', we update the mesh.rotation.y with tween.js until mesh.rotation.y is rotated in a 90 degree angle.
//SCENE, MESH,.. SETUP
...
function rotateRight(){
var start = {x:cubeMesh.rotation.x, y:cubeMesh.rotation.y, z:cubeMesh.rotation.z};
//RIGHT: y + 90°
var end = {x:cubeMesh.rotation.x, y:cubeMesh.rotation.y + degreeToRadians(90),
z:cubeMesh.rotation.z};
var tween = new TWEEN.Tween(start)
.to(end, 1000)
.easing( TWEEN.Easing.Exponential.InOut )
.onUpdate(function(){
cubeMesh.rotation.x = this.x;
cubeMesh.rotation.y = this.y;
cubeMesh.rotation.z = this.z;
})
.start();
}
function animateScene(){
requestAnimationFrame(animateScene);
TWEEN.update();
renderer.render(scene, camera);
}
What do I need to change to keep this cube rotating in the right directions? Can we fix the axes of the cube so they won't shift? I've read something about world axis vs object axis, is this something I need to change and how can I implement this?
Thanks in advance!
Sorry, cannot comment and this is for sure not the perfect answer but if you have problems with the rotation, maybe your tweening is not quite right?
What strikes my eye is that your function is only doing rotation on 1 axis and still you update all three axes. Maybe you should leave away x and z and only update the correct axis? Maybe this helps with your problem, too because you know what you are actually changing. It is just an idea , though.
Figured it out, thanks to this post:
How to rotate a 3D object on axis three.js?
Turned the object around the world axes.
Related
I want to rotate the wheels of a car in two directions, up when the car is moving forward and when it's moving in the left/right direction. But, when I'm try to move the wheels after rotate left/right, the rotation still apllys in the up direction, creating a strange circular movement. I did using
// to rotate in the Y axis
if (keyboard.pressed("left")) {
wheel.rotation.y -= 0.01
}
if (keyboard.pressed("up")) {
// to rotate in the X axis
wheel.rotation.x -= 50
}
Image of the car
It may sound silly, but have you tried using the 'z' axis instead of the 'y'?
As I didn't find an existing three.js quadcopter model, I'm trying to simulate one.
I created this "plus" symbol, but I'd like to orientate it as a "cross" symbol, i.e. rotated by +45° or -45° latitudinally
I don't mean this:
mesh.rotation.y+=THREE.Math.degToRad(45);
because I need to rotate it transversely like this:
https://jsfiddle.net/vcoumu83/25/
I mean that when I move the mouse on the X axis, the cross should rotate horizontally and not diagonally, on the dotted axis of the image
UPDATE
I'd like to achieve this:
While Brakebein answer is correct I think that maybe it would be simpler for you to just realign the geometry on the XY plane instead of the XZ, and then rotate it on the Z axis.
var x1=new THREE.BoxGeometry(25,1,1);
var x2=new THREE.BoxGeometry(1,25,1);
...
mesh.rotation.z = THREE.Math.degToRad(45);
Check lines 36-37 of this jsfiddle.
I'm not sure, what you want exactly. But if I add these lines, it looks like your image:
mesh.rotation.x = THREE.Math.degToRad(90);
mesh.rotation.y = THREE.Math.degToRad(45);
See updated jsfiddle: https://jsfiddle.net/vcoumu83/30/
Update: You need to set rotation.y to the new rotate value.
mesh.rotation.y = THREE.Math.degToRad(x);
https://jsfiddle.net/vcoumu83/46/
I'm trying to scale and then rotate a triangle and then translate it to a given point in Snap SVG.
I want to rotate the triangle around the top of it not the center, so i can build something like a pie.
So I thought I scale first, then rotate and later translate.
var t = new Snap.Matrix();
t.scale(0.5);
t.rotate(45, bbox.cx, (bbox.cy-(bbox.h/2)));
But the scale and rotation somehow are allways a bit off.
I reused a jsfiddle I found and updated it, so you can see what I try:
http://jsfiddle.net/AGq9X/477/
Somehow the bbox.cx and bbox.cy are not in the center of the triangle.
On my local setup they are.
The strange thing is, just rotation without scaleing works fine,
but scaling and then roation always seems to be a bit off on the y axis, the triangle doesn't stays at the rotation point.
Any ideas how i can fix that?
EDIT:
Ok I found the Solution,thanks to lan, you were right, the center of scaleing is important, and
I thought it was useing the center of the object, but it was the upper left corner. I adjusted it
and now it works greate:
var bbox = obj.getBBox(); //get coords etc. of triangle object
var t = new Snap.Matrix();
var offset = (bbox.cy+(bbox.h)) - centerY; //translate Y to center,
//depends on scaleing factor (0.5 = bbox.h, 0.25 = bbox.h*2)
t.scale(0.5, 0.5, bbox.cx, (bbox.cy+(bbox.h/2))); //scale object
t.translate(0,-offset); //translate to center
t.rotate(45, bbox.cx, (bbox.cy+(bbox.h/2))); //rotate object
obj.transform(t); //apply transformation to object
EDIT2:
I wanted to know how to save transformation, so you don't need to apply them every time you use a new transformation. Ian recommended to use element.transform() like so to get the old transformations:
element.transform( element.transform() + 's2,2' )
This is slightly more complicated than one would expect, but you would be animating a matrix, which does some odd things sometimes.
Personally I would use Snaps alternate animate method Snap.animate() and not using a matrix. Set the scale first and then build your animation string.
Something like..
var triangle2 = p.select("#myShape2").transform('s0.5');
...
Snap.animate(0,90,function( val ) {
triangle2.transform('r'+ val + ',' + bbox.cx+','+(bbox.cy-(bbox.h/2))+'s0.5')
}, 2000)
jsfiddle
I have some experience on Blender 3d, but almost none on 3d programing and I've trying to work with three.js now.
My question is: I have a simple cube and I rotated it around y-axis; then I need to rotate it again around y-axis, but as if the axis was rotated too. On Blender I would press RKEY twice.
To rotate first time I used: cube.rotation.y += Math.PI*.5;
How can I do that in Three.js? I've tried some matrix transformations too, but I could get done.
--
#muimota help me with a jfiddle, then I'm completing my explanation below:
Thanks #muimota, this example will help me to explain what I'm trying to do! Here is a changed fiddle with a more clear explanation: the cube was rotated two times (y and z) and then will be rotated infinitely on y axis. What I trying to do is to make it always rotate parallels with one of its faces – just like first rotation was parallels to its top face.
If you rotate a cube 90º every frame it will look the same and you might think it didn't rotate (but it did).
Here is an example:
http://jsfiddle.net/Lbabobdx/
function render() {
//ROTATES 90º every frame looking the same
mesh.rotation.y += Math.PI/2;
renderer.render(scene, camera);
}
I'm experimenting with three.js and the deviceorientation event. I'm rotating a cube with my phone's accelerometer, using the technique used in the THREE.DeviceOrientationState plugin. Basically the coordinates from the deviceorientation event angles are converted to radians and applied to a meshes' rotation coordinates (mesh.rotation.x, etc). Pretty basic.
This technique works fine as long as the phone is not rotated more than 90 degrees, but once it hits 90 degrees the rotation get messed up and the cube basically "flips". Not sure how else to describe it. Also, rotation works perfectly when rotating on only one axis, but as soon as two or more axis are involved and the phone is rotated more than 90 degrees we have problems.
Basically I need to know how to combine more than one rotation angle so that the cube rotates with the phone no matter how much the phone is rotated. The cube should always mimic the rotation of the phone. (I know, it's a bit weird to do that since you can't see the phone screen when it has been rotated so much, but bear with me, I have a plan.)
I thought maybe I was hitting gimbal lock, so tried using quaternions, but I get the same results. To be honest, I'm a little embarrassed to be asking this question. It has been a while since I did any 3D programming, but I feel like I should know how to do this.
Here's some example code. What else do I need to do to combine the rotation angles?
$(window).on('deviceorientation', function(e) {
var x = (!e.originalEvent.beta ? 0 : e.originalEvent.beta) * Math.PI / 180;
var y = (!e.originalEvent.gamma ? 0 : e.originalEvent.gamma) * Math.PI / 180;
var z = (!e.originalEvent.alpha ? 0 : (e.originalEvent.alpha - 180)) * Math.PI / 180;
cube.rotation.x = x;
cube.rotation.y = y;
cube.rotation.z = z;
});
UPDATE: Here is a jsfiddle that illustrates the issue. It has been modified to use the DeviceOrientationControls feature, which is now included in three.js. You'll see that the problem persists. Basically I need the cube to mimic the orientation of the phone exactly, no matter how much I turn the phone.
UPDATE 2: I changed the shape in the above jsfiddle from a cube to a 3d rectangle that is in the shape of a phone. I think it's easier to see what's happening with a rectangle than a cube.