Building rotation matrices from the ground up, with every multiplication worked by hand, ending at the orientation matrix the balancing robot gives its IMU.
I write these while learning the topic, to check I understand it. If
something here is wrong, I'd like to know.
This note builds rotation matrices from the ground up and shows the arithmetic in detail.
Convention used in this note
right-handed coordinate system
column vectors
active rotations: the vector rotates while the coordinate frame stays fixed
positive rotations follow the right-hand rule
Other conventions exist, so always check the one used by a robotics library or lecture.
What a rotation matrix is trying to do
Suppose a robot has a vector pointing in some direction:
v=[xy]or in 3Dv=xyz
A rotation matrix changes the direction of that vector without changing its length. The basic operation is:
v′=Rv
where v is the original vector, R is the rotation matrix and v′ is the rotated vector.
The matrix does not mean “multiply matching-looking numbers together”. Matrix multiplication follows a specific row-by-column rule.
Matrix multiplication refresher
Suppose:
A=[acbd],v=[xy]
The first answer value comes from the first row of the matrix dotted with the vector, ax+by. The second comes from the second row, cx+dy. So:
Av=[ax+bycx+dy]
Worked mini-example
A=[2435],v=[1020]
First row times the column:
(2)(10)+(3)(20)=20+60=80
Second row times the column:
(4)(10)+(5)(20)=40+100=140
Therefore:
Av=[80140]
You always use addition between the products. For a rotation matrix, the negative signs are already built into the matrix entries.
The standard 2D rotation matrix
The standard counterclockwise 2D rotation matrix is:
R(θ)=[cosθsinθ−sinθcosθ]
where θ is the rotation angle. Multiplying it out row-by-column:
[x′y′]=[cosθsinθ−sinθcosθ][xy]
The first row gives:
x′=xcosθ−ysinθ
and the second:
y′=xsinθ+ycosθ
Worked 2D examples
Rotate (1, 0) by 90°
We expect a vector pointing along positive x to rotate counterclockwise until it points along positive y. At 90∘, cos90∘=0 and sin90∘=1, so:
(1,1) already points at 45∘. Rotating it another 45∘ should make it point straight up, and it does.
Direction convention
With this convention a positive angle is counterclockwise and a negative angle is clockwise. A clockwise rotation by θ is R(−θ), and using cos(−θ)=cosθ and sin(−θ)=−sinθ:
R(−θ)=[cosθ−sinθsinθcosθ]
Example: clockwise 90°
R(−90∘)=[0−110]
Applied to (1,0):
x′=(0)(1)+(1)(0)=0y′=(−1)(1)+(0)(0)=−1
which is exactly a 90∘ clockwise turn from positive x.
Moving from 2D to 3D
In 3D the rotation matrix is 3×3. The key idea:
When rotating around one axis, the coordinate along that axis stays unchanged.
Rotating around the z-axis changes x and y and leaves z alone. That is why the 2D rotation pattern appears inside each 3D matrix.
Rotation about the x-axis
Rx(ϕ)=1000cosϕsinϕ0−sinϕcosϕ
ϕ is commonly used for roll. The first row, [100], guarantees x′=x while the y-z plane rotates.
z=3 did not change, because z was the rotation axis. This is a useful way to reconstruct the three standard matrices rather than memorising them: the axis row and column are zeros with a 1 where they cross, and the other four entries are the 2D pattern.
Properties of rotation matrices
A valid pure rotation matrix satisfies:
RTR=I
which means its rows and columns are mutually perpendicular unit vectors. It follows that:
R−1=RTdet(R)=1
A determinant of −1 would indicate a reflection rather than a proper rotation.
Checking it for 90° about z
RTR=0−10100001010−100001
The top-left entry is row 1 of RT dotted with column 1 of R: (0)(0)+(1)(1)+(0)(0)=1. The entry beside it is (0)(−1)+(1)(0)+(0)(0)=0. Continuing gives the identity, confirming the matrix preserves lengths and angles.
Undoing a rotation
If v′=Rv, then v=R−1v′, and because R−1=RT:
v=RTv′
For example, Rz(90∘) took (1,0,0) to (0,1,0), and its transpose takes (0,1,0) straight back to (1,0,0).
Robotics interpretation
Rotation matrices mostly appear when moving a vector between coordinate frames. Suppose a camera sees a point as pC=(1,0,2), where the subscript C means “expressed in the camera frame”. A matrix BRC describes how the camera axes are oriented relative to the robot body frame B, and:
pB=BRCpC
expresses the same physical vector in the body frame. This is where careful frame notation becomes important.
Project connection: the balancing robot’s IMU
The balancing-car firmware gives the MPU6050 DMP this orientation matrix:
S=−1000−10001
For a sensor-frame vector vs=(xs,ys,zs), the body-frame components are vb=Svs:
The sensor’s x and y are reversed while z stays unchanged, and that is exactly Rz(180∘), because cos180∘=−1 and sin180∘=0. The sensor is mounted rotated half a turn about the vertical axis.
Common mistakes
Multiplying element-by-element.Rv is row-by-column multiplication, not matching entries.
Changing the plus signs. A row [0−10] times (0,1,0) is (0)(0)+(−1)(1)+(0)(0). The negative comes from the matrix entry, not from switching to subtraction.
Mixing degrees and radians. Hand calculations use degrees; robotics software almost always uses radians, 90∘=2π. In NumPy:
theta = np.deg2rad(90)
Mixing active and passive rotations. An active rotation rotates the vector. A passive rotation changes the frame used to describe the same vector. They are related by the transpose, so a sign or transpose difference can appear between textbooks.
Summary
The main operation is v′=Rv, and one output number is one matrix row dotted with the vector column.
Rotation preserves length.
The rotation-axis coordinate stays unchanged; the other two behave like a 2D rotation.
The transpose reverses a proper rotation.
Multiplication order matters when combining rotations, which is where Euler angles come in next.