How to calculate angle between two 2D matrix transform? - c#

I have two 2D objects and each one has a transform matrix in C#.
in fact one of these gets from rotation of the other one.
How can I calculate the angle between these two matrix?
Is there any method that can do it directly?

Any 2D angle transform rotating through an angle θ will look like this:
| cos(θ) -sin(θ) 0 |
T = | sin(θ) cos(θ) 0 |
| 0 0 1 |
If you multiply your two transformation matricies together you'll get another one that's of the same form. It should be easy to calculate the angle.

It depends on how matrix is stored, but usually it's stored in "column based" order, which means
XAxis_x YAxis_x Offset_x
XAxis_y YAxis_y Offset_y
0 0 1
So if you get XAxis like a vector from one matrix and XAxis from another, you can measure angle between those 2 vectors. After measure in the same way an angle between YAxises of both matrices. So at the end you will have 2 angles: Rx, Ry, which applying on first matrix, will generated you the second one.

Related

How to I calculate clock-angle on x-y axis using C#?

We have a monitoring application that can monitor in intervals like 5 minutes, 15 minutes, 1 hour, etc. That's represented on the x-axis; The y-axis is also scalable and have values like 1.2345 - 1.5567 or can be switched to values like 26000 - 30000, etc.
Once the scale is set on the x and y axis, they don't dynamically change without a whole complete data refresh.
That being said, we only want certain people to be notified depending on the clock angle, of say, the last 5 intervals along the y axis.
The clock angles will never go counter-clockwise past 0/12; likewise, they'll never go past 6 clockwise.
I know the 3 o'clock angle is obvious when the x axis value is exactly the same as it was 5 intervals ago.
But how does one even start coding for everything in between? I can get the differences in x values easily (in the example graphic below, it's 0.3), and the difference in the y-axis in the below graphic is 4.
So with trigonometry that's opposite over adjacent, which means a tan operation I believe? If so, 0.3/5 doesn't seem to yield any values that seem like a clock angle.
Since I can't get any farther than that, I have no idea how it would be coded in C# other than calculating the differences.
Any help would be greatly appreciated!
You should be using atan2 (wiki , docs)
From the wiki:
atan2(y, x) returns the angle θ between the ray to the point (x, y) and the positive x axis, confined to (−π, π]
Note that the result is in radians, so you need to convert it if you want degrees
As stated, one radian is equal to 180/π degrees. Thus, to convert from radians to degrees, multiply by 180/π.
A couple of things here. First I think what you are asking for is the angle φ below, given two data points (x1,y1) and (x2,y2).
The problem here is that the angle is measuring the indicated triangle in pixels and not in x, y units.
So it is incorrect to do var φ = Math.Atan( (y2-y1)/(x2-x1) ); because the x and y axis have different units and angles are always dimensionless.
What additional information is needed, is the size of the graph area in pixels, as well as the range of values. Alternatively, the scaling gx,gy in pixels/unit for both axis.
For example, if the x-axis needs 45 pixels to span 1 grid of 1 hour (60 minutes) then te scaling is double gx = 45/60.0, and if the y-axis needs also 45 pixels to span 1 grid of 0.1 value then double gy = 45/0.1.
Then you can use this to calculate the sides of the triangle in pixels before calculating the angle
var adjacent = gx*(x2-x1); // convert x-axis units to pixels
var opposing = gy*(y2-y1); // convert y-axis units to pixels
var φ = Math.Atan(addjacent/opposing) * (180/Math.PI);
The last part calculates the angle φ and converts it from radians to degrees.

Find Angle Between Two Vectors

I have read some of the duplicate answers about angle between two vectors, but I'm still stuck with my problem. I have two vectors and I want that the angle between them to always be 90 degrees. To achieve that I need to find the angle between them, so that I can subtract or add the correct amount of degrees so that the angle between them always is 90 degrees.
The picture illustrates a sprite and two vectors. How do I find the angle A between them two? I have tried to use this code to get the angle between two vectors, but I must have missed something out, because I don't get the correct results:
public float GetAngleBetween (Vector2 A, Vector2 B)
{
float DotProd = Vector2.Dot (A, B);
float Length = A.Length () * B.Length ();
return (float)MathHelper.ToDegrees ((float)Math.Acos (DotProd/Length));
}
Any input is welcome and thank you in advance for any answers.
The actual angle in radians is
Math.ACos(Vector2.Dot(a, b));
Make sure that a and b are normalized vectors or the results can get pretty weird.
I think you may be looking for the Vector2.Dot method which is used to calculate the product of two vectors, and can be used for angle calculations.
For example:
// the angle between the two vectors is less than 90 degrees.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) > 0
// the angle between the two vectors is more than 90 degrees.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) < 0
// the angle between the two vectors is 90 degrees; that is, the vectors are orthogonal.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == 0
// the angle between the two vectors is 0 degrees; that is, the vectors point in the same direction and are parallel.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == 1
// the angle between the two vectors is 180 degrees; that is, the vectors point in opposite directions and are parallel.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == -1
Is this what you're looking for, or do you need the exact angle?
If I understand your question diagram and comments, the Dot product and Acos are not the only bits of info you need. You also need to account for when the sprite is not located at (0,0).
float angleInRadians = (float) Math.Acos(Vector2.Dot(Vector2.Normalize(vector1 - spritePosition), Vector2.Normalize(vector2 - spritePosition)));
int angleInDegrees = MathHelper.ToDegrees(angleInRadians);

Which algorithm helps me offset sensor fused data?

I have this sensor fused data coming from a GYRO-ACC-MAG-hardware sensor.
It's data (YAW-PITCH-ROLL) goes from -180 to +180 or -90 to +90
Which algorithm helps me offset this to an arbitrary position and also have no sign change to minus?
What I mean is: -180 to +180 for instance leads to 0 to 359. And I want 0 not where 0 of the sensor is but also offset to a certain position. In other words, picture a circle. Now put a zero at an arbitrary position on that circle. Now rotate that circle around it's center point. The zero rotates along, so it is now at a different position than it was before, right? That's the idea.
What I did:
YAW + 180 leads to 0 to 359. Pitch + 90 leads to 0 to 179. Roll + 180 leads to 0 to 359.
If I understand you correctly, you want to make use of the modulo operator:
double YAW360 = (YAW+180)%360;
See http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx
The modulo operator makes a division and returns the division remainder:
17 / 5 = 3 rest 2
Therefore:
17 % 5 = 2

Getting rotation axis from initial and final rotated quaternions

I have to find the axis and angle of rotation of a camera with an UP and Direction vector(They both are perpendicular to each other). I have the initial and final positions of the UP and direction vectors of the camera that is rotated. I want to find the axis and angle of the rotation for the camera. I am using C# for my project. I am new to this 3D rotation. So pardon my questions if you find them silly.
From the direction (forward) vector f and up vector u you can get the side vector s by performing a vector cross product (s = f x u). All three vectors are now orthogonal. You should also make them orthonormal by normalizing each one of them. Taken together, these vectors form an orthonormal basis.
You now have two such basis: the one from your initial camera orientation and the one from your final camera orientation. Both basis can be represented as a rotation matrix. A rotation matrix is simply a 3x3 matrix where the 3 rows are respectively:
The forward vector
The up vector
The side vector
For example, the matrix:
[[1 0 0]
[0 1 0]
[0 0 1]]
could be your initial camera orientation at start-up with its forward vector, up vector and side vector pointing towards the positive x axis, y axis and z axis, respectively.
You can now convert these two basis (M1 and M2) to two unit quaternions (Q1 and Q2) using this algorithm which takes care about potential problems like divides by zero.
At this point, you have two unit quaternions representing your initial and final camera orientation. You must now find the quaternion qT that transforms Q1 into Q2, that is:
q2 = qT * q1
q2 * q1^-1 = qT * (q1 * q1^-1) = qT
=> qT = q2 * q1^-1
Knowing that the inverse of a unit quaternion is equal to its conjugate:
q1^-1 = q1* iif ||q1|| = 1
qT = q2 * q1^-1 = q2 * q1*
There is a single step left: extracting the axis and angle from quaternion qT:
angle = 2 * acos(qw)
x = qx / sqrt(1-qw*qw)
y = qy / sqrt(1-qw*qw)
z = qz / sqrt(1-qw*qw)
The angle is, of course, given in radian. Beware of the divide by zero when calculating x, y and z. This situation would happen when there is no rotation or a very small one, so you should test if angle > epsilon where you would choose epsilon to be quite small an angle (say 1/10 of a degree) and not calculate the vector if that is the case.

Direct X Rotation / C# how to get two mesh objects to always face each other

Is there a way given the center point of a mesh object to always have it face another given point? For example if a cylinder is drawn so it looks like a cone always have the tip of the cone face some other given point?
Well thats definitely doable. You need to set up an orthonormal basis such that the 2 objects point each other. I'm going to assume that your cone is set up such that the point is down the Z-Axis (You need to bear this in mind).
Cone A is at position P
Cone B is at position Q
The direction from A to B is = Q - P and B to A is P - Q. Firstly we need to normalise both of these vectors so they are now unit direction vectors. We'll call them A' and B', respectively, for convenience (These are both now direction vectors).
We can assume, for now, that the up vector (We'll call it U) is 0, 1, 0 (Be warned that the maths here will fall over if A' or B' is very close to this up vector but for now I won't worry about that).
So we now need the side vector and true up vector. Fortunately we can calculate something that is perpendicular to the plane formed by the Up vector and A' or B' using a cross product.
Thus the side vector (S) is calculated as follows ... A' x U. Now we have this side vector we can calculate the true Up vector by doing A' x S. This now provides us with the 3 vectors we need for an orthonormal basis. You could normalise thse 2 vectors to remove any errors that may have accumulated but a cross product of 2 unit vectors should always be a unit vector so any errors would be slight so its probably not worth doing.
Using this information we can now build the matrix for Cone A.
S.x, S.y, S.z, 0
U.x, U.y, U.z, 0
A'.x, A'.y, A'.z, 0
P.x, P.y, P.z, 1
Perform the same calculations for both cones and they will now point towards each other. If you move either cone re-calculate as above again for both cones and they will still point towards each other.
Its worth noting that the matrix format I've used is DirectX's default (row major) layout. Its quite possible that C# (and thus XNA?) uses a column major format. If so you need to lay the amtrices out as follows:
S.x, U.x, A'.x, P.x
S.y, U.y, A'.y, P.y
S.z, U.z, A'.z, P.z
0, 0, 0, 1
Note the only difference between the 2 matrices is the fact that the rows and columns have been swapped. This makes the second matrix the transpose of the 1st matrix (And vice versa).

Categories

Resources