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);
Related
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 can get horizontal rotation angle by calculating the roll value (according to the definition of iOS Device Motion) when the device is portrait.
The x, y, z-axis of the mobile device:
But when the device is in landscape, y-axis is horizontal and x-axis is vertical. How can I get the angle? The pitch value is not correct. I have tried to exchange x and y in quaternion but not worked.
And more, how can I get the angle when the device is in the middle of portrait and landscape, for example, you tilt the device 30 degrees about z-axis?
Is there a unified quaternion or rotational matrix to calculate the angle whatever device orientation?
Probably you want to get angle of some device "direction". For example if you want to get angle of Z axis projected on ground, do it exactly.
Transform the Z(0,0,1) vector into current device rotation.
You have direction of "ZinWorld" vector in some world frame.
According to world frame orientation , project "ZinWorld" into ground plane. For example , if in default world frame Z is pointing to UP , then just take X Y components of "ZinWorld".
Take atan2(X, Y) to get proper angle.
I am using the Rotation Vector sensor to try to track how many degrees rotation 0-360 around the X axis (aka wrist movement) the user moves.
I am using the SensorManagers getOrientation to the the yaw, pitch and roll this way
float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(rotationMatrix, sensorData.getValues());
float[] orientation = new float[3];
SensorManager.getOrientation(rotationMatrix, orientation);
with the watch face pointing up it gives 0 degrees like I want but when I rotate I only get +/- 90 degree increments. rotating left gives me +90 degrees and rotating right gives me -90 degrees. I i continue rotating lets say from the +90 degrees I start getting negative degrees so when the watch is face down (180 degrees) is shows 0 again. using 90 degree increments is going to make it difficult to accurately get the actual rotation angle.
Is there a way to go from +/- 90 degree increments to 0-360 degrees?
You can use the z rotation value to find out whether the watch is face up or down. This determines the perspective you are viewing from and gives you 4 quadrants, instead of the 2 that you started with.
If z is positive: watch is face up. If z is negative, it is face down.
From here, you can create a coordinate system for conversion.
If the watch is facing up, coordinate is 90+x_rotation. Since rotating right gives [-90,0), and rotating left yields [0,90], this gives degrees of [-90+90,90+90] = [0, 180] Which is what we would expect of a watch facing up on the wrist.
If the watch is facing down, coordinate is 270+x_rotation. Quadrant 3 gives negative values of 90, making the values range from [270+-90,270] = [180,270]. Likewise, Quadrant 4 has positive values of 90, creating a range of [270,90+270]. So a watch facing down gives [180, 360].
Combined, we get the complete [0,360] device rotation range.
Hope this helps!
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 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))