I need to compare the relative angle of the wrist between two IMUs with the angle obtain from the Vicon but I have a problem. The relative angle obtained from the two IMUs is in the form 'roll, pitch and yaw' but from the Vicon Cameras I obtained only one absolute angle. In order to obtain the angle from the Vicon, I calculated the forearm plane and the hand plane, then I calculated the normal vectors of these planes and at the end from the two normals I obtain the relative angle between the hand and the forearm planes. How I can obtain three values (roll, pitch, yaw) from the relative Vicon angle in order to compare the two systems?
Thanks a lot for the help:)
Related
Given a point in 3D space, what are the three angles (e.g. Euler angles) needed to transform a line to point to that object?
Imagine I have a line (or a box) in 3D and I want to transform its heading, pitch, and bank to point to the 3D point from the origin, what values would I use for those angles?
I can't figure out the math to calculate the angles to point to a location such as (1,2,3).
Note: Instead of "yaw, pitch, roll", I'm going to use the conventions "heading, pitch, bank" as defined by 3D Math Primer for Graphics and Game Development by Fletcher Dunn.
Firstly, notice that in a 2D coordinate system, you only need a single angle + magnitude to "point" to any point in 2D.
Similarly, in a 3D coordinate system, you only need two angles + magnitude to "point" to any point in 3D. The last angle ("bank" or "roll") does not affect the location of a point in 3D. Instead it "spins" the arrow that would point to it. If the object is 360 degrees symmetrical, you won't see spin affecting the object at all. If the object is not symmetrical (e.g. an airplane) it will affect the object (e.g. tilting one wing towards the ground and the other towards the sky).
So the original question actually becomes, "how do I find the heading angle, pitch angle, and magnitude to "point" to any point in 3D space?"
You can easily figure this out using trigonometry functions. Imagine we have the point (1,2,3) and we're trying to calculate the heading, pitch, magnitude.
For the following example, let's use this diagram, where the left axis is X, up is Y, and right is Z. The point (1,2,3), then is represented by the blue sphere.
1. Find the magnitude
First, let's find the easiest value, the magnitude. Luckily for us, the magnitude (length) between any two points is easy to find no matter how many dimensions we are in, simply by using the Pythagorean theorem. Since we are in 3D and we're calculating the distance from the origin to our point, our distance formula becomes:
magnitude = sqrt(x*x + y*y + z*z)
Plugging in our actual values:
magnitude = sqrt(1*1 + 2*2 + 3*3)
= 3.7416573868
So our magnitude (or length) is ~3.741.
2. Find the heading
Next, to find the heading, notice that we just care about rotation about the XZ plane, and we don't care about the Y-axis at all. If we were to "flatten" the 3D space into 2D, it becomes trivial to find the heading.
We can draw a triangle that forms a 90 degree angle with the X-axis (red triangle) and then calculate that angle. Recall from trigonometry tan(angle) = opposite / adjacent, and solving for angle, we get angle = arctan(opposite / adjacent).
In this case "adjacent" is a known quantity (redAdjacent = x = 1), and "opposite" is known too (redOpposite = z = 3). Instead of using arctan to solve the equation though, we want to use atan2 since it'll handle all the different cases of x and y for us.
So we have:
heading = atan2(redOpposite, redAdjacent)
Plugging in our actual values:
heading = atan2(3, 1)
= 1.249045772398
so our heading is 1.249 rad, or ~72°.
3. Find the pitch
Finally we need to find the pitch. Similarly to what we did with the heading, we can flatten the the 3D space into 2D along the plane that contains these three points: (A) the origin (0,0,0), (B) our point (1,2,3), and (C) our point as it would project onto the XZ plane (1,0,3) (e.g. by setting 0 for the Y-value).
If we draw a triangle between all 3 of these points, you will notice that they form a right-triangle again (green triangle). We can simply calculate the angle using arctan2 again.
We already calculated the green hypotenuse in step 1 (i.e. the magnitude of our vector):
greenHypotenuse = sqrt(x*x + y*y + z*z)
= 3.7416573868
We also know the opposite of the green triangle is the same as the y-value:
greenOpposite = y
= 2
Using the pythagorean theorem, we can find the length of the adjacent angle:
greenOpposite^2 + greenAdjacent^2 = greenHypotenuse^2
y*y + greenAdjacent^2 = x*x + y*y + z*z
greenAdjacent^2 = x*x + z*z
greenAdjacent = sqrt(x*x + z*z)
Notice that another way to calculate the adjacent length of the green triangle is to notice that redHypotenuse == greenAdjacent, and we could find redHypotenuse using:
redHypotenuse^2 = redAdjacent^2 + redOpposite^2
= x*x + z*z
redHypotenuse = sqrt(x*x + z*z)
Plugging in actual values, we get:
greenAdjacent = sqrt(1*1 + 3*3)
= 3.1622776602
So now that we know the adjacent and opposite lengths of the green triangle, we can use arctan2 again:
pitch = atan2(greenOpposite, greenAdjacent)
= atan2(2, 3.1622776602)
= 0.563942641356
So our pitch is 0.5634 radians, or about 32°.
Conclusion
If you were to draw a line from the origin, with length 3.741, heading 1.249 rad, and pitch 0.564 rad, it would extend from (0,0,0) to (1,2,3).
I am working on a ray tracer and I got around to adding cylinders to the scene. The point I am stuck at is finding the surface normal vector in the point the ray hits. I need this to be able to do the diffuse lighting. What I have at this point is the 3d point where the camera ray hits the cylinder and the actual cylinder which is defined with a point on the central axis, the vector representing the direction of the axis and the radius. So to sum up my question, how do I find the normal vector in a point having the cylinder hit point, the radius, a point on its axis and the direction vector of the axis?
The cylinder normal vector starts at the centerline of the cylinder at the same z-height of the point where the ray intersects the cylinder, ends at the radial point of intersection. Normalize it and you have your unit normal vector.
If the cylinder centerline is not along the global z-direction of the scene you'll have to transform to cylinder coordinates, calculate the normal vector, and transform that back to global coordinates.
There are three possible situations:
the hit_pt is on the TOP CAP of the cylinder:
if (length(hit_pt - cy.top_center) < cy.radius)
surface_normal = cy.ori;
the hit_pt is on the BOTTOM CAP of the cylinder:
if (length(hit_pt - cy.bottom_center) < cy.radius)
surface_normal = -1 * cy.ori;
the hit_pt is on the SIDE of the cylinder. We can use dot product to find the point 'pt' on the center line of the cylinder, so that the vector (hit_pt - pt) is orthogonal to the cylinder's orientation.
t = dot((hit_pt - cy.bottom_center), cy.ori); // cy.ori should be normalized and so has the length of 1.
pt = cy.bottom_center + t * cy.ori;
surface_normal = normalize(hit_pt - pt)));
Given a plane(in my case a triangle) normal N_T and a reference Normal N_R, both have the length 1.
I calculated the rotation_normal
N = N_T x N_R
and now i need to calculate the angle around this rotation_normal, which i get with the following calculation:
angle = acos(<N_T, N_R>), with <x,y> is the dotproduct of x and y
This angle is in the interval of [0°, 180°] and is the smallest angle between both normals.
So my problem is that if i want to rotate my triangle in a manner that its normal is equal to the reference normal, i need to know in which direction (positive or negative) the calculated angle is.
Does anybody know how to get this direction or how to solve this problem in general?
you need to use atan2 (4-quadrant arc tangens)
create reference plane basis vectors u,v
must be perpendicular to each other and lie inside plane
preferably unit vectors (or else you need to account for its size)
so let N=N_T x N_R; ... reference plane normal where the rotation will take place
U=N_T;
V= N x U; ... x means cross product
make them unit U/=|U|; V/=|V|; if they are not already
compute plane coordinates of N_R
u=(N_R.U); ... . means dot product
v=(N_R.V);
compute angle
ang=atan2(v,u);
if you do not have atan2 then use ang=atanxy(u,v);
this will give you angle in range ang=<0,2*M_PI>
if you want signed angle instead then add
if (ang>M_PI) ang-=2.0*M_PI; ... M_PI is well known constant Pi=3.1415...
now if you want the opposite sign direction then just use -ang
Given circle centre: vectorA and another Vector on the circle's perimeter:vectorB, how can you determine the shorter route for vectorB to translate to another point on the circle's perimeter that is variable:vectorC? Will the shorter route be clockwise or counter clockwise rotation?
If it helps think of a clock. If the times is a random point on the clock's perimeter eg. 6, and the minute hand position is known, eg. 4. Does the hand need to rotate around the clock's centre point clockwise or counter clockwise to reach the random point (6)?
See also:
Vec1 = Circle centre, Vec2 = mousepos, find the point on the circle between Vec1, Vec2
Just compute winding direction of triangle ABC
so if you compute normal n=(B-A)x(C-B) where x is cross product then n.z sign determine the direction.
n.z = ((B.x-A.x)*(C.y-B.y)) - ((B.y-A.y)*(C.x-B.x))
if (n.z<0.0) dir=CW else dir=CCW;
that is all you need (CW means clockwise and CCW counter clockwise) of coarse if your coordinate system is different then the rotation can be negated
[Notes]
if (n.z==0) then the points B,C are either opposite or identical so direction does not matter because both ways the angular distance is the same
I have two points in 2D space, centred on origin (0,0). The first point represents the starting location and the second represents the end location. I need to calculate the angle of rotation between the two points, my problem being that the hypoteneuse from each point to (0,0) is not equal.
Could someone tell me how to work out the angle between the two points, bearing in mind that they could be anywhere relative to (0,0).
Many thanks,
Matt.
Let's say point 1 is (x1,y1) and point 2 is (x2,y2)
The tangent of the Angle from X axis to point 1, relative to (0,0) is y1/x1
The tangent of the Angle from X axis to point 2, relative to (0,0) is y2/x2
Take the arc tangent (is that the right term? Tan-1 on a calculator) to get the actual angle for each, then subtract to get the answer you're looking for
This is easily accomplished taking the arccosine of the normalized inner product of the two vectors. That is, given u = (ux, uy) and v = (vx, vy), the angle between the two is given by θ = acos(u·v/|u||v|), where u · v = uxvx + uyvy is the dot product of the two and the | | operator is the l2 normal given by |u| = sqrt(ux2 + uy2). This will result in the smallest rotation that can be applied to one of the vectors that will make them linear multiples of each other. Therefore, you may need to fiddle with the sign of θ to make sure you're going in the right direction if you have one you want to start from.