I'am totally beginner with Quaternion but I'am starting to use it. So I have a initial Quaternion for example Q = (0.95, -0.17, -0,06, 0.23) q0 from q3 left to right. I'd like to know how can I calculate the Quaternion who has rotate from 90° for example in x or z axis from my intial Quaternion Q, is it possible ? Should I multiply my Q by something ?
I found this code from Unity forum
var rotation = Quaternion.LookRotation(lookPos);
rotation *= Quaternion.Euler(0, 90, 0); // this adds a 90 degrees Y rotation
What I understand from these lines, rotation is the intial Quaternion after thaht we multiply initial quaternion by another Quaternion coming from a transformation Euler to Quaternion is it right?
Edit : I found this Quaternion, he represents a rotation to 90° in x axis Qr = (sqrt(0.5), sqrt(0.5), 0, 0) so if I multiply my initial Quaternion Q by Qr will I get my initial QUaternion rotate by 90° in x ?
Related
I have a point on a sphere that needs to be rotated. I have 3 different degrees of rotation (roll, pitch, yaw). Are there any formulas I could use to calculate where the point would end up after applying each rotation? For simplicity sake, the sphere can be centered on the origin if that helps.
I've tried looking at different ways of rotation, but nothing quite matches what I am looking for. If I needed to just rotate the sphere, I could do that, but I need to know the position of a point based on the rotation of the sphere.
Using Unity for an example, this is outside of unity in a separate project so using their library is not possible:
If the original point is at (1, 0, 0)
And the sphere then gets rotated by [45, 30, 15]:
What is the new (x, y, z) of the point?
If you have a given rotation as a Quaternion q, then you can rotate your point (Vector3) p like this:
Vector3 pRotated = q * p;
And if you have your rotation in Euler Angles then you can always convert it to a Quaternion like this (where x, y and z are the rotations in degrees around those axes):
Quaternion q = Quaternion.Euler(x,y,z);
Note that Unity's euler angles are defined so that first the object is rotated around the z axis, then around the x axis and finally around the y axis - and that these axes are all the in the space of the parent transform, if any (not the object's local axes, which will move with each rotation).
So I suppose that the z-axis would be roll, the x-axis would be pitch and the y axis would be yaw.You might have to switch the signs on some axes to match the expected result - for example, a positive x rotation will tilt the object downwards (assuming that the object's notion of forward is in its positive z direction and that up is in its positive y direction).
I have the green x,y points, how would I get the missing red?
You can rotate the two known points of 90° around their midpoint.
In pseudo code:
// Evaluate the midpoint from the coordinates of points a and b,
h_x = (b_x - a_x) / 2;
h_y = (b_y - a_y) / 2;
m_x = a_x + h_x;
m_y = a_y + h_y;
// Apply a rotation of 90 degree around the midpoint to find c and d
c_x = m_x - h_y;
c_y = m_y + h_x;
d_x = m_x + h_y;
d_y = m_y - h_x;
This result can be formally derived in terms of homogeneous coordinates and transfomation matrices.
The midpoint m, expressed in homogeneous coordinates, can be calculated as
To rotate a vector around the origin of an angle α, we apply a rotation matrix like
If another center of rotation is needed (the midpoint, in our case), we need to translate from the original position to the origin, apply the rotation and translate back again. The translation matrices are
The complete transformation can be expressed as
Where
So that we can evaluate, let's say d, with
Q.e.d.
I've got a function to return any points at which a line segment intersects a circle (up to two results, but potentially zero):
bool Math::GetLineCircleIntersections(Point theCenter, float theRadius, Point theLineA, Point theLineB, Array<Point>& theResults)
{
theResults.Reset();
Point aBA=theLineB-theLineA;
Point aCA=theCenter-theLineA;
float aA=aBA.mX*aBA.mX+aBA.mY*aBA.mY;
float aBBy2=aBA.mX*aCA.mX+aBA.mY*aCA.mY;
float aC=aCA.mX*aCA.mX+aCA.mY*aCA.mY-theRadius*theRadius;
float aPBy2=aBBy2/aA;
float aQ=aC/aA;
float aDisc=aPBy2*aPBy2-aQ;
if (aDisc<0) return false;
float aTmpSqrt=(float)sqrt(aDisc);
float aABScalingFactor1=-aPBy2+aTmpSqrt;
float aABScalingFactor2=-aPBy2-aTmpSqrt;
int aRSpot=0;
if (aABScalingFactor1<=0.0f && aABScalingFactor1>=-1.0f) theResults[aRSpot++]=Point(theLineA.mX-aBA.mX*aABScalingFactor1,theLineA.mY-aBA.mY*aABScalingFactor1);
if (aDisc==0) return true;
if (aABScalingFactor2<=0.0f && aABScalingFactor2>=-1.0f) theResults[aRSpot++]=Point(theLineA.mX-aBA.mX*aABScalingFactor2,theLineA.mY-aBA.mY*aABScalingFactor2);
return true;
}
I want to convert this to a 3D line, with an infinite cylinder-- with the added complication that the 3D cylinder has a tilt axis. I understand that what I'm really doing is intersecting with a sphere that is centered on the cylinder center where the plane of the line cuts it... but... how do I do that? How do I choose the best point to center the sphere, and then having done that, what's my change to turn line->circle intersections into line->sphere?
(I have a vector class that is exactly like the point class)
(Edit) I did manage to convert to a sphere function, only to discover that duh, no, a sphere won't work because a line that's tilted will not enter and exit the same way it would enter and exit a cylinder.
So, question is the same-- how can I convert this to collide with an infinite cylinder given an origin and axis for the cylinder?
I do not think sphere is usable for this...
However why not convert your 3D line into 2D by projecting it on to plane paralel with the cylinder base.
So you got 3D line in form of 2 endpoint p0,p1 and cylinder in form any point on its axis p , its radius r and axis unit direction vector d.
You need 2 unit basis vectors u,v describing cylinder base
so exploit cross product and cylinder axis for example:
// set u as any unit and non paralel vector to d
u = (1,0,0)
if (abs(dot(u,d))>0.75) u=(0,1,0)
// v set as perpendicular to u,d
v = cross(d,u)
// and make u perpendicular to v,d too
u = cross(v,d)
Project the problem into 2D
p0' = vec2( p0*dot(p0,u) , p0*dot(p0,v) )
p1' = vec2( p1*dot(p1,u) , p1*dot(p1,v) )
p' = vec2( p *dot(p ,u) , p *dot(p ,v) )
Solve the problem
now you just use 2D points p0',p1',p' and solve your problem using function you already have...
I have three non-colinear 3D points, let's say pt1, pt2, pt3. I've computed the plane P using the sympy.Plane. How can I find the orientation of this plane(P) i.e. RPY(euler angles) or in quaternion?
I never used sympy, but you should be able to find a function to get the angle between 2 vectors (your normal vector and the world Y axis.)
theta = yaxis.angle_between(P.normal_vector)
then get the rotation axis, which is the normalized cross product of those same vectors.
axis = yaxis.cross(P.normal_vector).normal()
Then construct a quaternion from the axis and angle
q = Quaternion.from_axis_angle(axis, theta)
I have two normalized vectors:
A) 0,0,-1
B) 0.559055,0.503937,0.653543
I want to know, what rotations about the axes would it take to take the vector at 0,0,-1 to 0.559055,0.503937,0.653543?
How would I calculate this? Something like, rotate over X axis 40 degrees and Y axis 220 (that's just example, but I don't know how to do it).
Check this out. (google is a good thing)
This calculates the angle between two vectors.
If Vector A is (ax, ay, az) and
Vector B is (bx, by, bz), then
The cos of angle between them is:
(ax*bx + ay*by + az*bz)
--------------------------------------------------------
sqrt(ax*ax + ay*ay + az*az) * sqrt(bx*bx + by*by + bz*bz)
To calculate the angle between the two vectors as projected onto the x-y plane, just ignore the z-coordinates.
Cosine of Angle in x-y plane =
(ax*bx + ay*by)
--------------------------------------
sqrt(ax*ax + ay*ay) * sqrt(bx*bx + by*by
Similarly, to calculate the angle between the projections of the two vectors in the x-z plane, ignore the y-coordinates.
It sounds like you're trying convert from Cartesian coordinates (x,y,z) into spherical coordinates (rho,theta,psi).
Since they're both unit vectors, rho, the radius, will be 1. This means your magnitudes will also be 1 and you can skip the whole denominator and just use the dot-product.
Rotating in the X/Y plane (about the Z axis) will be very difficult with your first example (0,0,-1) because it has no extension in X or Y. So there's nothing to rotate.
(0,0,-1) is 90 degrees from (1,0,0) or (0,1,0). If you take the x-axis to be the 0-angle for theta, then you calculate the phi (rotation off of the X/Y plane) by applying the inverse cos upon (x,y,z) and (x,y,0), then you can skip dot-products and get theta (the x/y rotation) with atan2(y,x).
Beware of gimbal lock which may cause problems.