Axis Rotation Question - math

By using left hand rule, I rotate one object left and right using y axis, and rotate up/down using x axis.
After first object is rotated to the right, the up/down rotation should be using z axis.
However, when I try to rotate using z axis, after the first rotation, it has the same effect when I rotate using y axis.
Anyone has any ideas?
Thanks

The proper order of rotations in order to keep everything straight is roll, pitch, yaw. That is, rotation around the X axis, rotation around the Y axis, rotation around the Z axis.

Not sure what your question is, but if you're asking why this happens, the answer is that rotations are not commutative. That is, a rotation of theta about axis A followed by a rotation of phi around axis B is not the same as rotation of phi around axis B followed by a rotation of theta around axis A.
If you're asking why a sequence of operations that seems okay when you visualise it fails to work in code, be sure you're using a right-handed coordinate system. Also, it might be helpful to work through your various rotation matrices for the x, y and z axes using the unit vector (1,0,0) - in fact, if you do it on paper you'll get a better intuition for what's happening.

Thanks for all the answers:
Sorry I didn't state the problem clearly.
That's the typical gimbal lock problem.
and my solution is to use quaternion rotation

Related

How do you rotate a quaternion a specified angle around the y axis?

I'm not quite sure if my question has been asked before in general terms. Whenever it has been asked, it is in terms of a specific language.
Let's say I have an objects rotation represented as a quaternion q = {w, x, y, z}.
I want to rotate this quaternion A radians around the y axis.
Since quaternions are already a measure of rotation, should I just add (or multiply) another quaternion representing the desired rotation to q? How would one go about this?
Thanks for your help.
You are right
Since quaternions are already a measure of rotation, should I just add (or multiply) another quaternion representing the desired rotation to q?
You should multiply current rotation quaternion with desired rotation quaternion. Depending on, local frame "Y" or global frame "Y" you should multiply from left to right or right to left.

Three.js - how do up vectors work with lookAt()?

I'm trying to understand how up vectors and lookAt() work together in three.js. I'm setting the up vector of this axisHelper, so that the Y axis always points at the target geo, which marks the position of the up vector. It works as expected for X and Y, rotating the axes around the Z axis; and when I try to adjust the Z value of the up vector I would expect the axes to rotate around the X axis, but nothing happens.
http://jsfiddle.net/68p5r/4/
[Edit: I've added geo to show the up target position.]
I have a dat.gui interface manipulating the up vector to demonstrate, but the problem exists when I set the vector manually as well.
I suspect the problem is around line 74:
zControl.onChange(function(value) {
axes.up.set(this.object.x, this.object.y, value);
axes.lookAt(new THREE.Vector3(0, 0, 1));
});
When I update the up vector, I instruct the axisHelper to update its orientation onscreen by redoing its lookAt() down its Z axis. Changing the X and Y works as expected, why not the Z?
(This is also the case if I use geo instead of an axisHelper: http://jsfiddle.net/68p5r/5/)
When you call Object.lookAt( vector ), the object is rotated so that its internal z-axis points toward the target vector.
But that is not sufficient to specify the object's orientation, because the object itself can still be "spun" on its z-axis.
So the object is then "spun" so that its internal y-axis is in the plane of its internal z-axis and the up vector.
The target vector and the up vector are, together, sufficient to uniquely specify the object's orientation.
three.js r.63
Tip: An axis in three.js should always have unit length; be sure to call axis.normalize() in your code.
I assume your title meant rotate on Z instead of X?
Anyways, the culprit seems to be axes.lookAt(new THREE.Vector3(0, 0, 1)); if you change that to axes.lookAt(new THREE.Vector3(0, 1, 0)); for all methods then Y doesn't rotate as expected. You are telling the axis helper to look down a specific axis (in your case Z). Hence why Z value isn't working.
Is there an example of what your trying to accomplish that might help us?
Maybe someone else can give a bit more in depth explanation of what's happening. Hopefully my answer will push you in the right direction.
Here's how I came to understand the problem:
The lookAt and up vectors determine the orientation of an object like so:
The lookAt vector is applied FIRST, which sets the X and Y rotations, locking the direction the object's Z axis points.
THEN the up vector determines how the object rotates around the Z axis, to set the direction the object's Y axis points -- it won't affect the X and Y rotations at all.
In my example, the axisHelper is looking down its blue Z axis in the direction of the lookAt vector, which is a point in space at (0, 0, -1) -- so the X and Y rotations have already been set. The only thing left to do is figure out how to rotate the axisHelper around its Z axis, which means setting the X and Y points of the up vector -- moving the up vector forward and backward along the Z axis won't change anything.
Here's a fiddle with a demo illustrating this relationship: the blue arrow is the lookAt axis, and the green arrow is the up axis.
https://jsfiddle.net/hrjfgo4b/3
Links to jsfiddle.net must be accompanied by code

How to find the x and y coordinates of a circle given a plot, the original rotation, the new rotation, the origin and radius?

The easiest way I know how to explain this is with a picture so here it is:
http://pbrd.co/19RxqqV
For simplicity the origin is 0,0 and the angles are easy to work with but they could potentially be anything. The only things I really consistently know for this type of problem is the rotation of the circle, the origin and the radius and then of course the new degree/rotation of the circle.
This question, I think is similar but not really the exact same thing:
Finding the coordinates on the edge of a circle
Thanks! I hope my question is clear enough.
The coordinates of a point with angle a with respect to x-axis on a circle of radius r are:
x = r*cos(a*Pi/180), y = r*sin(a*Pi/180)
In your case a=45+135

3d rotation around the origin

I know there are plenty of questions about 3d rotation that have been answered here but all of them seem to deal with rotational matrices and quaternions in OpenGL (and I don't really care if I get gimbal lock). I need to get 3d coordinates EX:(x,y,z) of a point that always must be the same distance, I'll call it "d" for now, from the origin. The only information I have as input is the deltax and deltay of the mouse across the screen. So far here is what I have tried:
First:
thetaxz+=(omousex-mouseX)/( width );
thetaxy+=(omousey-mouseY)/( height);
(thetaxy is the angle in radians on the x,y axis and thetaxz on the x,z axis)
(I limit both angles so that if they are less than or equal to 0 they equal 2*PI)
Second:
pointX=cos(thetaxz)*d;
pointY=sin(thetaxy)*d;
(pointX is the point's x coordinate and pointY is the y)
Third:
if(thetaxz)<PI){
pointZ=sqrt(sq(d)-sq(eyeX/d)-sq(eyeY/d));
}else{
pointZ=-sqrt(abs(sq(d)-sq(eyeX/d)-sq(eyeY/d)));
}
(sq() is a function that squares and abs() is an absolute value function)
(pointZ should be the point's z coordinate and it is except at crossing between the positive z hemisphere and negative z hemisphere. As it approaches the edge the point gets stretched further than the distance that it is always supposed to be at in the x and y and seemingly randomly around 0.1-0.2 radians of thetaxz the z coordinate becomes NAN or undefined)
I have thought about this for awhile, and truthfully I'm having difficulty warping my head around the concept of quaternions and rotational matrices however if you can show me how to use them to generate actual coordinates I would be glad to learn. I would still prefer it if I could just use some trigonometry in a few axis. Thank you in advance for any help and if you need more information please just ask.
Hint/last minute idea: I think it may have something to do with the z position affecting the x and y positions back but I am not sure.
EDIT: I drew a diagram:
If you truly want any success in this, you're going to have to bite the bullet and learn about rotation matrices and / or quaternion rotations. There may be other ways to do what you want, but rotation matrices and quaternion rotations are used simply because they are widely understood and among the simplest means of expressing and applying rotations to vectors. Any other representation somebody can come up with will probably be a more complex reformulation of one or both of these. In fact it can be shown rotation is a linear transformation and so can be expressed as a matrix. Quaternion rotations are just a simplified means of rotating vectors in 3D, and therefore have equivalent matrix representations.
That said, it sounds like you're interested in grabbing an object in your scene with a mouse click and rotating in a natural sort of way. If that's the case, you should look at the ArcBall method (there are numerous examples you may want to look over). This still requires you know something of quaternions. You will also find that an at least minimal comprehension of the basic aspects of linear algebra will be helpful.
Update: Based on your diagram and the comments it contains, it looks like all you are really trying to do is to convert Spherical Coordinates to Cartesian Coordinates. As long as we agree on the the notation, that's easy. Let θ be the angle you're calling XY, that is, the angle between the X axis rotated about the Z axis; this is called the azimuth angle and will be in the range [0, 2π) radians or [0°, 360°). Let Φ be an angle between the XY plane and your vector; this is called the elevation angle and will be in the range [-π/2, +π/2] or [-90°, +90°] and it corresponds to the angle you're calling the XZ angle (rotation in the XZ plane about the Y axis). There are other conventions, so make sure you're consistent. Anyway, the conversion is simply:
x = d∙cos(Φ)∙cos(θ)
y = d∙cos(Φ)∙sin(θ)
z = d∙sin(Φ)

Camera rotation with a quaternion

I am having a problem with the maths of camera rotation, well more like I lack knowledge on this subject and can't find anything about it on the internet (read, most likely don't know the correct search keywords)
Anyway, this is what I am attempting to do (pseudo code):
RotateCamera(angle,axis){
Quaternion rotation = cam.getRotation();
Quaternion rot = new Quaternion();
rot.fromAngleNormalAxis(angle, axis);
rotation.multLocal(rot);
cam.setRotation(rotation);
}
update(float value){ // just to show what input I use the RotateCamera method for the directions
RotateCamera(value,Vector3f(0,1,0)) // left
RotateCamera(-value,Vector3f(0,1,0)) // right
RotateCamera(value,Vector3f(1,0,0)) // up
RotateCamera(-value,Vector3f(1,0,0)) // down
}
Now this works quite well but sometimes the cam will roll instead of only yaw/pitch. What is the correct way of doing this?
With just the bit of code given, it's hard to say for sure. But it looks like you've hard coded the axes of rotation into your update method. The thing about rotations (whether represented by quaternions or matrices) is that their multiplication isn't "commutative" meaning doing the same two rotations but in opposite orders does not give the same result.
It looks like you're assuming the camera is facing in the (0,0,1) direction, let's call it the z axis, with the y axis (0,1,0) coming out of the top of your head. As long as this assumption holds, you're axis of rotation for looking up, down, left and right will be (1,0,0), (1,0,0), (0,1,0) and (0,1,0) as they seem to be in your code snippet. But say you've just rotated 90 degrees to the left. This sends the camera's view from the (0,0,1) direction to the (1,0,0) direction. Now say you make an "up" rotation, which was coded to be around the (1,0,0) axis. This is a rotation around the same axis in which you're looking, and the effect will be a roll.
Does this address the issue? If so, you should code your axes of rotation w.r.t. the current direction the camera is facing.

Resources