Animation time based on quaternion difference - c#

I'm trying to adjust the orientation of my camera using two quaternions, based on their difference. So for a minimal rotation, I want the animation to take little time, and a bigger rotation to take longer. I guess I want to rotate the camera at a certain velocity.
Is there any way to combine the yaw, roll and pitch to get a single radian, so I can use that to calculate what percentage of the quaternion I want to apply each frame?

If you vant to differenciate the two quaternion just use the ToAngleAxis of the delta quaternion. It returns the angle (you need this) and the axix of the rotation between the two quaternions.
You can use quaternions and the calculated speed to calculate spherical interpolation (slerp for short), which allows you to calculate intermediate states for your camera orientation.

Related

Calculate degrees from a 2D heading vector

I am trying to add sprites to a game I am currently working on. I have sprites for north, south, west & east directions. I've already found how to get a direction from degrees, the problem is that I can't seem to calculate the right amount of degrees (0° to 360°) from a normalized velocity vector, called heading. Check figure 1 below for my velocity vector, my heading vector is a normalized clone of this vector.
What I want to achieve is that:
A property degrees: returns the right amount of degrees, based on a current heading/velocity vector.
A method receiving degrees as parameter, which in turn can return a direction which I can use when drawing my sprite.
Figure 1: my 2D velocity vector
My code for calculating the heading vector:
Vector2D heading = Velocity.Clone.Normalize();
I am also not sure if using a heading vector is necessary, so if it's possible or preferred to use the velocity vector, please tell me and include this in your answer.

Flatten a Quaternion Rotation into 3 Unit Axes Rotations

Hi I have an arbitrary rotation quaternion, which is constructed from a series of operations done by the user (they select the object, rotate it around the plane constructed from the camera view direction, then maybe rotate it from another angle etc).
I then need to decompose this rotation object down into a rotation around the X, Y and Z axes. Note that it doesn't have to be that order. The user interface allows a user to attach rotation blocks together in any order, so they could chain them up like this:
In code, I then loop through each block and do:
finalRotation *= Quaternion.CreateFromAxisAngle(blockAxis, toRadians(blockAngle))
So how could I convert an arbitrary quaternion back to this block representation? I've tried projecting the quaternion onto the X, Y and Z planes as per this answer:
Component of a quaternion rotation around an axis
and then connecting up the blocks in an [X][Y][Z] order, but so far the results seem to come out incorrectly. Would someone be able to explain how I should approach this problem? Note I am restricted to rotating around one axis at a time, per block.
Edit: To clarify I am using the MonoGame framework, not Unity.

How can I find the rotation of the head in Google Cardboard Unity3D?

Hey guys how do I find the rotation of the phone with Google Cardboard SDK in Unity3D, like the way the persons head is facing? I need to find if it is facing more towards the east, the west, or the north. Do I find the rotation of the head, or the parent Main camera?
The Cardboard class contains a property called HeadRotation which is a Quaternion.
Quaternion crtRot = youCardboardController.HeadRotation;
To use its rotation like you'd in Unity with directional vectors you may simply multiply it by Vector3.forward.
Vector3 lookDir = crtRot * Vector3.forward;
Visualizing the vector in editor might help narrow down issues
void Update () {
// ..
Debug.DrawRay( pos, lookDir * 100, Color.blue );
// ..
}
From here you only need to know where North is, in meaning of the facing vector. Do a Vector3.Angle() and you have the angle between your avatar's and North's vector. You might want to evaluate both vectors with their y axes set to 0.
You could also use Vector3.Dot() (the dot product) to determine how much both vectors look into the same direction.
I had an issue with HeadPosition, which wasn't updated properly. So if you operate from HeadPosition keep in mind it may stick to 0,0,0 .
Take Head.transform.rotation - that's the orientation of the user's head.
I'm not really sure what do you mean by North or West. If the mobile device has a magnetometer, then maybe you could read it's data to determine where North is, but I've never done that
It would be the rotation of the Head object, although the Main Camera usually has the same rotation.
But if you want the direction relative to the real world, that information is not available in the SDK. The compass cannot be used because of the magnet, so there is no way to get the real direction.
Just take the rotation angle of the main camera in the scene. It will gives you the head rotation angles with respect to x, y and z axis.
In GVR based VR scenes the system is internally rotating the camera with respect to our head movements. So it's easy to get the head rotation using main camera rotation angles.
For that,
//local rotation of the Transform of the camera
Camera.main.transform.localEulerAngles.y
//The world Y rotation
Camera.main.transform.rotation.y

Calculate the initial velocity needed for a ball to hit a target

How would I get the initial velocity needed for a bullet to hit a target when the following are all constants
time to target
gravity
initial position of the ball and the target
radius of the ball
I am doing out a few examples in Unity 3D using c# for the code. I am not asking for the code, I just would like to know what steps to take to do this (physics wise).
Your question can be solved using Kinematics. You need to know a few things about Physics, but it is all very simple.
When the bullet is fired the only force acting on the bullet is gravity.
Acceleration on the x-axis will be 0.
Acceleration on the y-axis will be gravity.
Let us examine what we know:
time
gravity
distance_to_target
To calculate you will need these equations:
VelocityFinal_x = VelocityInitial_x
FinalDistance_x - InitialDistance_x = VelocityInitial_x * time
VelocityFinal_y = VelocityInitial_y + gravity * time
Just rearrange the second equation to find VelocityInitial_x
Notice that we didn't need to use z-axis. Don't touch the z-axis unless the wind is moving the bullet in mid-flight.
Make sure you do these calculations once at the instant the bullet is fired, don't do it every frame of the game.
A nice article on Wiki regarding trajectory of projectile with detailed explanation of two-dimensional case (3D case may be easily reduced to 2D if you define a plane included start point of projectile, target point and vector of gravity).
To hit a target at range x and altitude y when fired from (0,0) and with initial speed v the required angles of launch theta are:

XNA Rotating a tank properly

Im making a 2D game where the player controls a tank.
I can make the tank, and all, but whats really messing with my mind is how to make it rotate accordingly.
I want it to behave just like the Wii game, Tanks.
Fixed directions, and with no real front and back on the tank.
Driving up, then left should make it rotate to the left.
Driving up, then down should not make it rotate, just drive the other direction.
I red a tutorial a while back about some way to do that by dividing the degrees into 2 180 degree parts. But i have simply not been able to find that damn site again.
I hope you guys are able to understand what im trying to say.
Thanks in advance :)
I assume you're drawing your tank as a sprite? In that case there's an overload of the SpriteBatch.Draw method that allow you to specify the rotation angle around the origin.
SpriteBatch.Draw overload
Here's an example on how to use it from MSDN
The example above will keep rotating your sprite, so you will need to add some custom logic so it will only rotate it according to keyboard input. Here's a simple example on how to check for keyboard input. So add logic that checks if the right or left button has been pressed, and update the rotation angle if they have. If it's the up or down button that has been pressed you simply modify the position of your sprite.
I hope it makes sense, otherwise just let me know.
I think what you're looking for is simply the best way to minimize the rotation of the tank, modulo 180 degrees.
I would use the angle between the desired movement direction and the tank's current direction to start. Make sure this is the minimum angle, then compare that with the angle between the tank's current direction + 180 degrees. Something like:
// smallest angle between the current direction and the desired direction
minAngle1 = Math.Abs(Math.Min(tankAngle - desiredAngle, desiredAngle - tankAngle));
// smallest angle between the opposite direction and the desired direction
oppositeAngle = (tankAngle + 180) % 360;
minAngle2 = Math.Abs(Math.Min(oppositeAngle - desiredAngle, desiredAngle - oppositeAngle));
// get the smaller of two to rotate to
if (minAngle1 < minAngle2) {
// we know that we should rotate the current direction to the desired direction
} else {
// rotate the opposing direction to the desired direction
}
Note you'll need to play with your rotation signs to ensure you're rotating the right way. Also, I've assumed you know your rotation angles, if you have vectors you can simplify this a little bit by using the dot product between the two vectors instead of the angle for comparisons.
Is your problem with the direction of movement based on the angle they have rotated?
Vector2 moveDir = new Vector2(Math.Cos(rotation), Math.Sin(rotation));
position += (moveDir * speed);
Speed here would be a number for how fast you want to move in that direction. position is another Vector2 for the position of the sprite. As Tchami says you can draw it with the rotation using the SpriteBatch.Draw overload. Rotation for the the Cos and Sin methods should be in radians but I think Draw should be in degrees if I remember correctly. MathHelper.ToRadians(degrees) and MathHelper.ToDegrees(radians) should solve that.
There is lots of XNA tutorials and examples on the site http://creators.xna.com/en-US/education/catalog/

Categories

Resources