2d rotation

A 2d rotation has only one parameter θ, when the basis vectors i^=[1,0] and j^=[0,1] are rotated by an angle θ

p=cosθi^+sinθj^q=sinθi^+cosθj^

Which builds the rotation matrix

R(θ)=[pq]=[cosθsinθsinθcosθ]

When a vector v is transformed by this matrix we know that the vector will be a linear combination of the basis which are p and q

v=vR(θ)=vxp+vyq=vx[cosθsinθ]+vy[sinθcosθ]=[vxcosθvysinθvxsinθ+vycosθ]T

Using a matrix to encode this operation

v=vR(θ)=[vxvy][cosθsinθsinθcosθ]=[vxcosθvysinθvxsinθ+vycosθ]T

See also complex numbers

3d rotation

About cardinal axes

Rx(α)=[1000cosαsinα0sinαcosα]
Ry(β)=[cosβ0sinβ010sinβ0cosβ]
Rz(γ)=[cosγsinγ0sinγcosγ0001]

See also

About an arbitrary axis

Given an axis n^ and an amount of rotation around it θ our goal is to find a rotation matrix that rotates about n^ by th angle θ

v=R(n^,θ)v

The basic idea is to solve this problem in a plane perpendicular to n^ which becomes a 2d problem

Separate v in two vectors, a vector parallel to v^ called v and a vector perpendicular to v^ called v such that v+v=v

v=(vn^)n^v=vv

After the rotation it’s obvious that the v component will be the same and only the vector v will be rotated

A plane can be defined with two vectors that lie on it, since we have v and we also know the normal of the plane (which is n^) any vector perpendicular to both vectors will also lie in the plane, we can use the cross product to find this vector

w=n^×v

The length of w is

w=n^vsin90°=v

Which means that w has the same length as v, note that even though they have the same length they don’t necessarily have unit length

w and v form now a 2d coordinate space where the x-axis is v and the y-axis is v

Let v be a vector that is the result of rotating v by an angle θ, we can find the projection of it onto the x-axis and the y-axis as follows

v,x=(vcosθ)v^=cosθvv,y=(vsinθ)w^=sinθw
  • Expressing v as a linear combination of the basis
v=cosθv+sinθw

Reconstructing the solution from the observations above

v=(vn^)n^v=vv=v(vn^)n^w=n^×v=n^×(vv)=n^×vn^×v=n^×v

Finally

v=v+v=cosθv+sinθw+(vn^)n^=cosθ(v(vn^)n^)+sinθ(n^×v)+(vn^)n^=cosθvcosθ(vn^)n^+sinθ(n^×v)+(vn^)n^(1)=cosθv+sinθ(n^×v)+(1cosθ)(vn^)n^

Now we can compute what the basis vectors are after the transformation above (by using each of the basis vectors as v on (1)) to construct a rotation matrix

p=[100]p=[nx2(1cosθ)+cosθnxny(1cosθ)+nzsinθnxnz(1cosθ)nzsinθ]q=[010]q=[nynx(1cosθ)nzsinθny2(1cosθ)+cosθnynz(1cosθ)+nxsinθ]r=[001]r=[nznx(1cosθ)+nysinθnzny(1cosθ)nxsinθnz2(1cosθ)+cosθ]

Constructing the matrix from these vectors

R(n^,θ)=[pqr]

3d rotations using quaternions

A complex rotor is a unit norm complex number which rotates another complex number by the angle θ and has the form

eiθ=cosθ+isinθ

Hamilton had hoped that a unit-norm quaternion q could be used to rotate a vector which is stored as a pure quaternion p, the unit norm quaternion is given by

(2)q=[s,λn^]s,λR,n^R3|n^|=1s2+λ2=1
p=[0,v]vR3

Let’s compute the product p=qp

p=qp=[s,λn^][0,v](3)=[λn^v,sv+λn^×v]

Special case

What if n^ is perpendicular to v? Then the scalar quantity of (3) is zero and we are left with the pure quaternion

(4)p=[0,sv+λn^×v]given that n^ is perpendicular to n

Let’s analyze the vector part of (4) (which is now a 3d entity because it’s a pure quaternion), since n^ is perpendicular to v then the vector n^×v will have a norm equal to n^×v=n^vsin90° and also since n^ is a unit vector then n^×v=v which means that we have two orthogonal vectors with the same length

To rotate the vector v about n^ let’s transform v to the 2d space whose basis vectors are v and n^×v and perform the rotation there which is trivially [cosθ,sinθ], therefore all we have to do in (4) is make the scalar quantities multiplying each vector equal the projection of the rotated vector over the basis

p=[0,cosθv+sinθn^×v]

Which makes the quaternion q have the form

(5)q=[cosθ,sinθn^]

And it acts as a rotor only when n^ is perpendicular to v

Important notes/facts about orthogonal quaternions

  • If q is a rotor about the unit vector n^ by an angle θ whose vector term is perpendicular to the pure quaternion p
    • qp and pq1 rotate p by an angle θ about n^
    • pq and q1p rotate p by an angle θ about n^
    • Each of these products leave p unscaled (because q is a unit norm quaternion)

General case

Let’s use (2) as the starting point, note that this time its vector part it’s not necessarily perpendicular to the pure quaternion p, the product qp yields

qp=[s,λn^][0,v]=[λn^v,sv+λn^×v]

Note that the term λn^v does not vanish since for the general case n^ and v are no longer perpendicular, what’s more important is that the product qp is no longer a pure quaternion, multiplying a vector by a non-orthogonal quaternion has converted some of the vector information into the quaternion’s scalar component

What happens if we post-multiply qp by q1, could it reverse the operation? (Note that since q is a norm quaternion q1=q)

qpq1=[λn^v,sv+λn^×v][s,λn^]

Let’s first check if doing this multiplication makes the scalar component vanish

qpq1=[λsn^v(sv+λn^×v)(λn^),]=[λsn^v+(sv)(λn^)+(λn^×v)(λn^),]=[λsn^v+(sv)(λn^)+0,]since n^ is perpendicular to n^×v =[λsn^v+λsvn^),]=[0,]

Indeed it magically made the scalar component vanish! Now let’s look at the vector component of qpq1

qpq1=[0,s(sv+λn^×v)+(λn^v)(λn^)+(sv+λn^×v)×(λn^)]=[0,s2v+sλ(n^×v)+λ2(n^v)n^sλ(v×n^)λ2(n^×v×n^)]

Let’s expand the cross product

(n^×v)×n^=(n^n^)v(vn^)n^=v(vn^)n^

Therefore

qpq1=[0,s2v+sλ(n^×v)+λ2(n^v)n^sλ(v×n^)λ2(v(vn^)n^)]=[0,s2v+sλ(n^×v)+λ2(n^v)n^sλ(v×n^)λ2v+λ2(vn^)n^)]=[0,s2v+2sλ(n^×v)+λ2(n^v)n^λ2v+λ2(vn^)n^)]=[0,(s2λ2)v+2sλ(n^×v)+2λ2(vn^)n^]

Let’s make s=cosθ and λ=sinθ just like in (5) (it worked as a rotor when it was orthogonal to p, it might work with the general case too)

qpq1=[0,(cos2θsin2θ)v+2cosθsinθ(n^×v)+2sin2θ(vn^)n^]

Which involves double-angle terms, replacing these terms with double angle-identities

qpq1=[0,cos2θv+sin2θ(n^×v)+(1cos2θ)(vn^)n^]

The product created a pure quaternion equal to v rotated by an angle 2θ, if we want to rotate v by an angle θ we must build a half angle θ quaternion q (note above that q was equal to (5))

(6)q=[cos12θ,sin12θn^]

Using (6) the product is

qpq1=[0,cosθv+sinθ(n^×v)+(1cosθ)(vn^)n^]

Note that the vector part of qpq1 is identical to (1)

Quaternion difference and dot product

Let a and b be two unit norm quaternions (rotors that have the same form as (6)), the quaternion to rotate from a to b is given by da=b and is known as quaternion difference, finding the value of d given that we know a and b

da=bd(aa)=basince a is a unit norm quaternion its inverse is equal to its conjugated=ba

Expanding the product

d=[sb,b][sa,a]=[sbsa+ba,sba+sabb×a]

Note that the scalar part of this quaternion is equal to the inner product (a generalization of the dot product to abstract vector spaces) between two quaternions

d=[a,b,sba+sabb×a]

Remembering that a rotor is given by (6) we can relate the inner product between rotor quaternions with the scalar quantity of (6) and interpret it geometrically just like the dot product between two vectors in 3d/2d space but this time noticing that the dot product gives the cosine of half the angle between the quaternions

ab=cosθ2

This means that the angle between a and b is equal to

θ=2arccos(ab)

Or using the half angle formulas

cos2θ2=12(1+cosθ)(ab)2=12(1+cosθ)cosθ=2(ab)21θ=arccos(2(ab)21)

The second formula works for all the cases as noted here (the first one doesn’t work when ab<0)