I want to rotate the cube when the user is touching it. To rotate it,is quite simple but actual problem is if the user is tilting it then always it should stop in particuler face(cube has 6 faces and i mean that only one face should be visible at one time). Please give your suggetion if anyone worked on that.
In the case of a cube this is simple: Face normals are the cartesian axes. So one looks straigt on a face if you constrain the rotations around the cartesian axes (X, Y, Z) and the rotation angles are multiple of pi/2 = 90°.
So in your code when the user stops interacting, set the rotation angles to the next multiple of 90°
fmod(round(angle/90) * 90, 360); // degrees
fmod(round(angle/(pi/2)) * pi/2, 2*pi); // radians
Either do it hard, or animate it.
If your object is not a cube, but arbitrary, you need to find the additional rotation for the face to get perpendicular to the view axis. This angle is determined by acos( scalar_product(normalize(face_normal), normalize(view_axis)) ) the axis of rotation is given by cross_product(normalize(face_normal), normalize(view_axis))
Related
The definition of 'roll' in android is:
angle between a plane perpendicular to the device's screen and a plane perpendicular to the ground
See here.
Maybe I'm missing something, but there seem to be many planes perpendicular to the ground giving many different angles.
Could someone please rephrase this definition using e.g planes parallel to ground or screen, north direction, gravity direction?
NB! I am asking for a rephrasing using different words. I know the official definition as I have stated. Please don't repost the official definition.
From the mentioned docs:
Roll, angle of rotation about the y axis. This value represents the
angle between a plane perpendicular to the device's screen and a plane
perpendicular to the ground.
From another doc:
Roll (degrees of rotation about the y axis). This is the angle between
a plane perpendicular to the device's screen and a plane perpendicular
to the ground. If you hold the device parallel to the ground with the
bottom edge closest to you and tilt the left edge of the device toward
the ground, the roll angle becomes positive. Tilting in the opposite
direction—moving the right edge of the device toward the ground—
causes the roll angle to become negative. The range of values is -90
degrees to 90 degrees.
You may also have a look at that picture
The important point is about the y-axis. The y-axis is the one that goes positive from the bottom edge to the upper edge of the screen.
----EDIT----
A may be much more explicit picture here.
values[2]: Roll, angle of rotation about the y axis. This value represents the angle between a plane perpendicular to the device's screen and a plane perpendicular to the ground. Assuming that the bottom edge of the device faces the user and that the screen is face-up, tilting the left edge of the device toward the ground creates a positive roll angle. The range of values is -π/2 to π/2.
The plane "perpendicular to the ground" here is just a reference for how "tilted" (rolled) the device is. Imagine the device flat on a table next to a wall. If you lift the edge of the device so it is tilted to the side, the angle of roll is the angle between the plane of the device and the plane of the wall. This is because we have constrained the x axis (pitch) so that you are looking at roll. Now, if you lift the top of the device towards you, the roll stays the same while the pitch changes, because the device is still at the same angle towards the wall along it's y axis.
I want to rotate the whole value of a 3d vector into one axis using quaternion rotations.
The reason behind is that I want to align the X and Y Axis of my smartphone with the X and Y Axis of my vehicle in order to detect lateral and longitudinal acceleration separated on these two axis. Therefore I want to detect the first straight acceleration of the car and rotate the whole acceleration value into the heading axis (X-Axis) of the phone assuming a straight forward motion.
How do I achieve this?
I got it myself while this Link helped me a lot.
In the end I just needed to define the destination axis as a Vector V(Magnitude_Source, 0, 0), calculate the angle between V and the source vector and rotate the source vector.
I want to set a 2D sprite's rotation so it faces the direction it's moving in. Currently I hooked the accelerometer to the sprite's linear velocity and when I tilt my device it doesn't rotate, only moves. I am running AndEngine on Android.
I want to calculate x+/x-/y+/y- to receive a value in rotation degrees.
atan2(y,x) should do the trick.
So if angle=0 is in positive x direction,
angle = Math.atan2(y_velocity, x_velocity);
gives you the angle you have to rotate.
Figured it out eventually, to achieve this I did the following:
float radians=(float)Math.atan2(-acceleration.x, acceleration.y); //No Idea why I had to invert x axiz but it wouldn't work without it being done
float degrees=(float)Math.toDegrees(radians)+90; //Had to rotate my sprite by 90 degrees
radians=(float)Math.toRadians(degrees);
sprite.setTransform(sprite.getWorldCenter(), radians);
When device is rotated by some amount, a simple cube has to rotate by the same amount but in the opposite direction. For example, the cube has to rotate to 45 degrees to the left if the device is rotated 45 degrees to the right. Or when pitch is 30 degrees, the cube has to rotate -30 degrees around X axis. When the yaw is 10 degrees, the cube has to rotate -10 degrees around Z axis. I've used .getRotationMatrixFromVector followed by getOrientation like so:
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
SensorManager.getRotationMatrixFromVector(
mRotationMatrix , event.values);
SensorManager.getOrientation(mRotationMatrix, orientationVals);
azimuthVal = (Math.round((Math.toDegrees(orientationVals[0]))*100.0)/100.0);
pitchVal= (Math.round((Math.toDegrees(orientationVals[1]))*100.0)/100.0);
rollVal = (Math.round((Math.toDegrees(orientationVals[2]))*100.0)/100.0);}
But the problem with it change in pitch affects roll and vice versa and as a result when device is rotated around X axis, the pinch value changes->roll changes -> the cube rotates not only around X but also around Y, when I don't need that.
I've looked around the internet and many refer to Quaternions as a solution but how can I apply quaternions to my specific application, as I need to know amount of degrees device is rotated by along an axes.
Gimbal lock happens when you want to extract (Euler) rotation angles from the rotation matrix, basically at some specific rotation we loose a degree of freedom in the equation between rotation matrix components and rotation angles and the actual rotation angles are not recoverable,
So in your code it may happen at :
SensorManager.getOrientation(mRotationMatrix, orientationVals);
You should somehow solve the issue before extracting the rotation angles,
this could be done by modifying the quaternion's components as is explained here:
http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
I'm trying to get billboarding to work, but having trouble with the last step.
After following these directions from NeHe's tutorials (http://nehe.gamedev.net/data/articles/article.asp?article=19) I have my look, right, and up vectors, and I have already translated the modelview matrix to the centerpoint of the billboard by using glTranslatef().
float[] m = {right.x,right.y,right.z,0f,
up.x,up.y,up.z,0f,
look.x,look.y,look.z,0f,
pos.x,pos.y,pos.z,1f}; //pos is the centerpoint position
gl.glMultMatrixf(m, 0);
When I try to create a multiplication matrix out of these like so, the billboards are displayed all over the place in the wrong positions and orientations.
I guess my problem is that I don't know how to correctly create and multiply the matrix. I tried doing this instead, but then half the lines (the ones that need to rotate counter-clockwise) are rotated in the wrong direction:
//normal is the vector that the billboard faces before any manipulations.
float angle = look.getAngleDeg(normal); //returns angle between 0 and 180.
gl.glRotatef(angle, up.x,up.y,up.z);
Got it, using my second method. Calculating the angle between vectors (arccos of the dot product) can only give an angle between 0 and 180, so half the time you want to negate the angle so the rotation is in the opposite direction.
This is easy to check...since I already have the right vector, I can just check if the angle between the right vector and the normal is acute. If it's acute, then you want to negate the original angle.