Can I get a single axis of a quaternion? - vector

I would like to rotate a quaternion about a specific axis. I tried q_rot*q_original, with q_rot a constant quaternion:
double factor = sin( a / 2.0 );
double x = xx * factor;
double y = yy * factor;
double z = zz * factor;
double w = cos( a / 2.0 );
Quaternion(x, y, z, w).normalize();
But in my case, q_original changes over time and I think xx, yy, and zz should therefore be dependent on q_original (or the coordinate system of q_original). So I now would like to get the rotation axis directly from q_original. Does someone know how I get one axis e.g. the y_axis (3 components) from a quaternion (4 components)?
Edit: For each time stamp I have a position (x,y,z) and an orientation represented by a quaternion (x,y,z,w). I would like to rotate this pose(position, orientation). To rotate it I need the axis of rotation of that single pose. How can I get this?
Thanks

Related

Given 2 vector and 2 angle how to find the 3rd vector

It seems to be a very easy question but I just can't figure it out ...
as shown on the below graph:
Supposing we know :
Vector (X,Y)
Vector (X1,Y1)
Angle a
How can I get the vector (?,?) in Unity ?
Many Thanks in advance.
Subtract X1,Y1 from all coordinates.
XX = X - X1
YY = Y - Y1
Let (DX, DY) is vector between (XX, YY) and unknown point.
This vector is perpendicular to (XX, YY), so scalar product is zero.
And length of this vector is equal to length of (XX, YY) multiplied by tangent of angle.
So equation system is
DX * XX + DY * YY = 0
DX^2 + DY^2 = (XX^2 + YY^2) * Tan^2(Alpha)
Solve this system for unknowns (DX, DY) (there are two solutions in general case), then calculate unknown coordinates as (X + DX, Y + DY)
Not totally sure if there is a more efficient method to do this, but it will work.
First you need to find the magnitude of the distance vector between X,Y and X1,Y1. We will call this Dist1.
Dist1 = Vector2.Distance(new Vector2(X,Y), new Vector2(X1,Y1));
Using this distance, we can find the magnitude of the vector for the line going to X?,Y? which we will call DistQ.
DistQ = Dist1 / Mathf.Cos(a * Mathf.Deg2Rad);
You now need to find the angle of this line relative to the overall coordinate plane which will create a new triangle with X?Y? and the x-axis.
angle = Mathf.Atan2((Y - Y1), (X - X1)) * Mathf.Rad2Deg - a;
Now we can use more trig with the DistQ hypotenuse and this new angle to find the X?(XF) and Y?(YF) components relative to X1 and Y1, which we will add on to get the final vector components.
XF = DistQ * Mathf.Cos(angle * Mathf.Deg2Rad) + X1;
YF = DistQ * Mathf.Sin(angle * Mathf.Deg2Rad) + Y1;

calculate angle from vector to coord

I am breaking my head trying to find an appropriate formula to calculate a what sounds to be an easy task but in practice is a big mathematical headache.
I want to find out the offset it needs to turn my vector's angle (X, Y, Angle) to face a coord ( X, Y )
My vector won't always be facing 360 degrees, so i need that as a variable as well..
Hoping an answer before i'm breaking my pc screen.
Thank you.
input
p1 = (x1,y1) point1 (vector origin)
p2 = (x2,y2) point2
a1 = 360 deg direction of vector
assuming your coodinate system is: X+ is right Y+ is up ang+ is CCW
your image suggest that you have X,Y mixed up (angle usually start from X axis not Y)
da=? change of a1 to match direction of p2-p1
solution 1:
da=a1-a2=a1-atanxy(x2-x1,y1-y1)
atanxy(dx,dy) is also called atan2 on some libs just make sure the order of operands is the right one
you can also use mine atanxy in C++
it is 4 quadrant arctangens
solution 2:
v1=(cos(a1),sin(a1))
v2=(x2-x1,y2-y1)
da=acos(dot(v1,v2)/(|v1|*|v2|))
or the same slightly different
v1=(cos(a1),sin(a1))
v2=(x2-x1,y2-y1)
v2/=|v2| // makes v2 unit vector, v1 is already unit
da=acos(dot(v1,v2))
so:
da=acos((cos(a1)*(x2-x1)+sin(a1)*(y2-y1)/sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)));
[notes]
just change it to match your coordinate system (which you did not specify)
use radians or degrees according to your sin,cos,atan dependencies ...
The difference between the vectors is also a vector.
Then calculate the tangens (y part / x part) and invert it to an angle.
Of course use the sign of y if x = 0.
if the coord to face is (x2 ,y2)
deltaY = y2 - y1
deltaX = x2 - x1
You have the angle in degrees between the two points using this formula...
angleInDegrees = arctan(deltaY / deltaX) * 180 / PI
subtract the original angle of your vector and you will get the correct offset!

Easiest way to rotate a rectangle

I'm using rectangles defined in terms of their x y coordinates and their width and height. I figured out how to rotate them in terms of coordinates (x = cos(deg) * x - sin(deg) * y y = sin(deg) * x + cos(deg) * y) but I'm stuck on the height and width. I'm sure there's an obvious solution that I'm missing. If it matters, I'm using Python.
edit Sorry for the confusing description. My intention is to get the width and height either reversed or negated due to whatever the angle is. For example, in a 90 degree rotation the values would switch. In a 180 degree rotation the width would be negative. Also, I only intend to use multiples of 90 in my script. I could just use if statements, but I assumed there would be a more "elegant" method.
Just calculate four corners of Your rectangle:
p1 = (x, y)
p2 = (x + w, y)
p3 = (x, y + h)
and rotate each by angle You want:
p1 = rotate(p1, angle)
# and so on...
and transform back to Your rectangle representation:
x, y = p1
w = dist(p1, p2) # the same as before rotation
h = dist(p1, p3)
where dist calculates distance between two points.
Edit: Why don't You try apply formula You have written to (width, height) pair?
x1 = cos(deg) * x - sin(deg) * y
y2 = sin(deg) * x + cos(deg) * y
It is easy to see that if deg == 90 the values will switch:
x1 = -y
y2 = x
and if deg == 180 they will be negated:
x1 = -x
y2 = -y
and so on... I think this is what You are looking for.
Edit2:
Here comes fast rotation function:
def rotate_left_by_90(times, x, y):
return [(x, y), (-y, x), (-x, -y), (y, -x)][times % 4]
The proper way would be to resort to transformation matrices. Also, judging from your question I suppose that you want to rotate with respect to (x=0,y=0), but if not you will need to take this into account and translate your rectangle to the center of the plan first (and then translate it back when the rotation is carried out).
M = Matrix to translate to the center
R = Rotation Matrix
Transformation Matrix = M^(-1) * R * M
But to give you an easy answer to your question, just take the two other corners of your rectangle and apply the same transformation on them.
To learn more about transformation matrices :
http://en.wikipedia.org/wiki/Transformation_matrix
From the way you describe only rotating by 90 degrees, and the way you seem to be defining width and height, perhaps you are looking for something like
direction = 1 // counter-clockwise degrees
// or
direction = -1 // clockwise 90 degrees
new_height = width * direction
new_width = -height * direction
width = new_width
height = new_height
Not sure why you want to have negative values for width and height, though .. because otherwise each 90 degree rotation effectively just swaps width and height, regardless which way you rotate.
Rotation should not change width and height. Your equation is correct if you want to rotate (x,y) about (0,0) by deg, but note that often cos and sin functions expect arguments in radians rather than degrees, so you may need to multiply deg by pi/180 (radians per degree).
If you need to find the locations of other rectangle vertices besides (x,y) after rotating, then you should either store and rotate them along with (x,y) or keep some information about the rectangle's orientation (such as deg) so you can recompute them as e.g. x+widthcos(deg), y+heightsin(deg).

How to calculate a point on a rotated axis?

How can I calculate a point (X,Y) a specified distance away, on a rotated axis? I know what angle I'd like the point "moving" along (in degrees).
x = cos(a) * d
y = sin(a) * d
where a is the angle and d is the distance.
If the trigonometry functions takes radians intead of degrees, you have to convert the angle by dividing by 180/pi.
Convert to polar coordinates and then rotate the point through the angle you want:
x = r * cos( theta );
y = r * sin( theta );
Note: theta in radians ( deg = rad * 180 / pi )
More info on polar coordinates.
Do you mean the 3d formulas? They are easy as well. But we need to know what's your convention for specifying the axis.

Plotting a point on the edge of a sphere

So coming from a flash background I have an OK understanding of some simple 2D trig. In 2d with I circle, I know the math to place an item on the edge given an angle and a radius using.
x = cos(a) * r;
y = sin(a) * r;
Now if i have a point in 3d space, i know the radius of my sphere, i know the angle i want to position it around the z axis and the angle i want to position it around, say, the y axis. What is the math to find the x, y and z coordinates in my 3d space (assume that my origin is 0,0,0)? I would think i could borrow the Math from the circle trig but i can't seem to find a solution.
Your position in 3d is given by two angles (+ radius, which in your case is constant)
x = r * cos(s) * sin(t)
y = r * sin(s) * sin(t)
z = r * cos(t)
here, s is the angle around the z-axis, and t is the height angle, measured 'down' from the z-axis.
The picture below shows what the angles represent, s=theta in the range 0 to 2*PI in the xy-plane, and t=phi in the range 0 to PI.
The accepted answer did not seem to support negative x values (possibly I did something wrong), but just in case, using notation from ISO convention on coordinate systems defined in this Wikipedia entry, this system of equations should work:
import math
x = radius * sin(theta) * cos(phi)
y = radius * sin(theta) * sin(phi)
z = radius * cos(theta)
radius = math.sqrt(math.pow(x, 2) + math.pow(y, 2) + math.pow(z, 2))
phi = math.atan2(y, x)
theta = math.acos((z / radius))

Resources