Angle, which way to rotate to - math

For a game i'm trying to calculate the angle between where i'm looking at and the position of another object in the scene. I got the angle by using the following code:
Vec3 out_sub;
Math.Subtract(pEnt->vOrigin, pLocalEnt->vOrigin, out_sub);
float angle = Math.DotProductAcos(out_sub, vec3LookAt);
This code does give me the angle between where im looking at and an object in the scene. But there's a small problem.
When i don't directly look at the object but slightly to the left of it, then it says i have to rotate 10 degrees in order to directly look at the object. Which is perfectly correct.
But, when i look slightly to the right of the object, it also says i have to rotate 10 degrees in order to look directly to the object.
The problem here is, the i have no way to tell which way to rotate to. I only know its 10 degrees. But do i have to rotate to the left or right? That's what i need to find out.
How can i figure that out?

I feel the need to elaborate on Ignacio's answer...
In general, your question is not well-founded, since "turn left" and "turn right" only have meaning after you decide which way is "up".
The cross product of two vectors is a vector that tells you which way is "up". That is, A x B is the "up" that you have to use if you want to turn left to get from A to B. (And the magnitude of the cross product tells you how far you have to turn, more or less...)
For 3D vectors, the cross product has a z component of x1 * y2 - y1 * x2. If the vectors themselves are 2D (i.e., have zero z components), then this is the only thing you have to compute to get the cross product; the x and y components of the cross product are zero. So in 2D, if this number is positive, then "up" is the positive z direction and you have to turn left. If this number is negative, then "up" is the negative z direction and you have to turn left while upside-down; i.e., turn right.

You also need to perform the cross product on the vectors. You can then get the direction of the rotate by the direction of the resultant vector.

Related

How to calculate a point on a circle knowing the radius and center point

I have a complicated problem and it involves an understanding of Maths I'm not confident with.
Some slight context may help. I'm building a 3D train simulator for children and it will run in the browser using WebGL. I'm trying to create a network of points to place the track assets (see image) and provide reference for the train to move along.
To help explain my problem I have created a visual representation as I am a designer who can script and not really a programmer or a mathematician:
Basically, I have 3 shapes (Figs. A, B & C) and although they have width, can be represented as a straight line for A and curves (B & C). Curves B & C are derived (bend modified) from A so are all the same length (l) which is 112. The curves (B & C) each have a radius (r) of 285.5 and the (a) angle they were bent at was 22.5°.
Each shape (A, B & C) has a registration point (start point) illustrated by the centre of the green boxes attached to each of them.
What I am trying to do is create a network of "track" starting at 0, 0 (using standard Cartesian coordinates).
My problem is where to place the next element after a curve. If it were straight track then there is no problem as I can use the length as a constant offset along the y axis but that would be boring so I need to add curves.
Fig. D. demonstrates an example of a possible track layout but please understand that I am not looking for a static answer (based on where everything is positioned in the image), I need a formula that can be applied no matter how I configure the track.
Using Fig. D. I tried to work out where to place the second curved element after the first one. I used the formula for plotting a point of the circumference of a circle given its centre coordinates and radius (Fig. E.).
I had point 1 as that was simply a case of setting the length (y position) of the straight line. I could easily work out the centre of the circle because that's just the offset y position, the offset of the radius (r) (x position) and the angle (a) which is always 22.5° (which, incidentally, was converted to Radians as per formula requirements).
After passing the values through the formula I didn't get the correct result because the formula assumed I was working anti-clockwise starting at 3 o'clock so I had to deduct 180 from (a) and convert that to Radians to get the expected result.
That did work and if I wanted to create a 180° track curve I could use the same centre point and simply deducted 22.5° from the angle each time. Great. But I want a more dynamic track layout like in Figs. D & E.
So, how would I go about working point 5 in Fig. E. because that represents the centre point for that curve segment? I simply have no idea.
Also, as a bonus question, is this the correct way to be doing this or am I over-complicating things?
This problem is the only issue stopping me from building my game and, as you can appreciate, it is a bit of a biggie so I thank anyone for their contribution in advance.
As you build up the track, the position of the next piece of track to be placed needs to be relative to location and direction of the current end of the track.
I would store an (x,y) position and an angle a to indicate the current point (with x,y starting at 0, and a starting at pi/2 radians, which corresponds to straight up in the "anticlockwise from 3-o'clock" system).
Then construct
fx = cos(a);
fy = sin(a);
lx = -sin(a);
ly = cos(a);
which correspond to the x and y components of 'forward' and 'left' vectors relative to the direction we are currently facing. If we wanted to move our position one unit forward, we would increment (x,y) by (fx, fy).
In your case, the rule for placing a straight section of track is then:
x=x+112*fx
y=y+112*fy
The rule for placing a curve is slightly more complex. For a curve turning right, we need to move forward 112*sin(22.5°), then side-step right 112*(1-cos(22.5°), then turn clockwise by 22.5°. In code,
x=x+285.206*sin(22.5*pi/180)*fx // Move forward
y=y+285.206*sin(22.5*pi/180)*fy
x=x+285.206*(1-cos(22.5*pi/180))*(-lx) // Side-step right
y=y+285.206*(1-cos(22.5*pi/180))*(-ly)
a=a-22.5*pi/180 // Turn to face new direction
Turning left is just like turning right, but with a negative angle.
To place the subsequent pieces, just run this procedure again, calculating fx,fy, lx and ly with the now-updated value of a, and then incrementing x and y depending on what type of track piece is next.
There is one other point that you might consider; in my experience, building tracks which form closed loops with these sort of pieces usually works if you stick to making 90° turns or rather symmetric layouts. However, it's quite easy to make tracks which don't quite join up, and it's not obvious to see how they should be modified to allow them to join. Something to bear in mind perhaps if your program allows children to design their own layouts.
Point 5 is equidistant from 3 as 2, but in the opposite direction.

Find how high up the camera is looking with a rotation Matrix

I'm working on an FPS with the jPCT library. One key thing that all FPS's need is to prevent the players from looking behind them by pulling the mouse too far up/down. Currently, I'm using some example code found on the jPCT's website that keeps track of how many angles have been added to the camera, but I'm worried about rounding issues with all the angles in radians. I can get a rotation Matrix from jPCT's camera, and I know that it contains the information to figure out how "high" up the player is looking, but I have no clue how to get it out of the matrix.
What would I look for in the rotation matrix that will tell me if the player is looking more "up" than strait up and more "down" than strait down?
If you're updating your matrix each time the player moves you're going to run into trouble due to floating point errors and your rotation matrix will turn into a skew matrix. One solution is to orthonormalise the matrix every now and then but usually it's better to simply keep the player's pitch, yaw (and roll if you need it) as floats and build your matrix from those angles when the player changes orientation, looks up/down etc. If you use optimised code for each angle (or a single method for converting Euler angles to a matrix) it's not slower than what you seem to be doing right now. You won't run into Gimbal lock issues as the camera orientation will be restricted anyway.
As for your specific question I think you'd need to calculate the angle between matrix Z axis (the third row or column, depends how your matrices are oriented) and an unrotated vector pointing down your Z axis.

Rotation of Tetrehedra for 3d Tessellation

I'm trying to render some 3d graphics with a bunch of tetrahedra. I'm trying to figure out how to rotate one tetrahedron such that it will be perfectly face-to-face with another tetrahedron. If this is confusing, multiple tetrahedra touching face to face would look like this.
I'm using OpenGL to programmatically rotate objects, so I can only rotate on one of the three axes at a time. For example, I can rotate clockwise 20 degrees on X, then counterclockwise 45 degrees on Z, etc.
I understand the programming aspect of this program (using OpenGL's glRotatef() function to rotate on one axis at a time), but am more interested in the specific angles needed for each axis in order to achieve the 3d tessellation.
Thanks for any help, let me know if you need more clarification.
If they need to be perfectly face to face, I would not try to find a rotation at all.
Instead, I would start with one tetrahedron. Decide which face is shared with the next one.
Take the cross product of two edges on this face (50% chance that it points in the direction of the 4th point, in this case invert the vector). Normalize. Multiply by sqrt(6)/3 * edge_length (this is a constant, precompute!).
You now have a vector pointing in the direction of the new tetrahedron's 4th vertex (the other 3 you already know, they're the same as the ones on the face!), with the length of the new tetrahedron's height.
All you now need is an origin for your vector: Take the arithmetic mean of the coordinates of the 3 shared vertices, that will give the center point of that face.
Add the vector to that point, giving you the final point.
Now you two tetrahedrons sharing one face (regardless of orientation), no rotation math needed.

Adjust camera co-ordinates to represent change in azimuth, elevation and roll values

I'm currently working with libQGLViewer, and I'm receiving a stream of data from my sensor, holding azimuth, elevation and roll values, 3 euler angles.
The problem can be considered as the camera representing an aeroplane, and the changes in azimuth, elevation and roll the plane moving.
I need a general set of transformation matrices to transform the camera point and the up vector to represent this, but I'm unsure how to calculate them since the axis to rotate about changes after each rotation ( I think? ).
Either that, or just someway to pass the azimuth, elevation, roll values to the camera and have some function do it for me? I understand that cameraPosition.setOrientation(Quaterion something) might work, but I couldn't really understand it. Any ideas?
For example you could just take the three matrices for rotation about the coordinate axes, plug in your angles respectively, and multiply these three matrices together to get the final roation matrix (but use the correct multiplication order).
You can also just compute a quaternion from the euler angles. Look here for ideas. Just keep in mind that you always have to use the correct order of the euler angles (whatever your three values mean), perhaps with some experimentation (those different euler conventions always make me crazy).
EDIT: In response to your comment: This is accounted by the order of rotations. The matrices applied like v' = XYZv correspond to roation about z, unchanged y and then unchanged x, which is equal to x, y' and then z''. So you have to keep an eye on the axes (what your words like azimuth mean) and the order in which you rotate about these axes.

Calculating rotation along a path

I am trying to animate an object, let's say its a car. I want it go from point
x1,y1,z1
to point x2,y2,z2 . It moves to those points, but it appears to be drifting rather than pointing in the direction of motion. So my question is: how can I solve this issue in my updateframe() event? Could you point me in the direction of some good resources?
Thanks.
First off how do you represent the road?
I recently done exactly this thing and I used Catmull-Rom splines for the road. To orient an object and make it follow the spline path you need to interpolate the current x,y,z position from a t that walks along the spline, then orient it along the Frenet Coordinates System or Frenet Frame for that particular position.
Basically for each point you need 3 vectors: the Tangent, the Normal, and the Binormal. The Tangent will be the actual direction you will like your object (car) to point at.
I choose Catmull-Rom because they are easy to deduct the tangents at any point - just make the (vector) difference between 2 other near points to the current one. (Say you are at t, pick t-epsilon and t+epsilon - with epsilon being a small enough constant).
For the other 2 vectors, you can use this iterative method - that is you start with a known set of vectors on one end, and you work a new set based on the previous one each updateframe() ).
You need to work out the initial orientation of the car, and the final orientation of the car at its destination, then interpolate between them to determine the orientation in between for the current timestep.
This article describes the mathematics behind doing the interpolation, as well as some other things to do with rotating objects that may be of use to you. gamasutra.com in general is an excellent resource for this sort of thing.
I think interpolating is giving the drift you are seeing.
You need to model the way steering works .. your update function should 1) move the car always in the direction of where it is pointing and 2) turn the car toward the current target .. one should not affect the other so that the turning will happen and complete more rapidly than the arriving.
In general terms, the direction the car is pointing is along its velocity vector, which is the first derivative of its position vector.
For example, if the car is going in a circle (of radius r) around the origin every n seconds then the x component of the car's position is given by:
x = r.sin(2πt/n)
and the x component of its velocity vector will be:
vx = dx/dt = r.(2π/n)cos(2πt/n)
Do this for all of the x, y and z components, normalize the resulting vector and you have your direction.
Always pointing the car toward the destination point is simple and cheap, but it won't work if the car is following a curved path. In which case you need to point the car along the tangent line at its current location (see other answers, above).
going from one position to another gives an object a velocity, a velocity is a vector, and normalising that vector will give you the direction vector of the motion that you can plug into a "look at" matrix, do the cross of the up with this vector to get the side and hey presto you have a full matrix for the direction control of the object in motion.

Resources