Rotate 3D point around 3D origin in radians using transformation matrices

I am attempting to make a function that can rotate a given 3D point around a 3D origin using transformation matrices.

I did ask this on StackOverflow but did not receive an answer: javascript - Rotate 3D point around 3D origin in radians using transformation matrices - Stack Overflow

I do not have experience with linear Algebra, so this is purely based on research.

I saw various other questions on the same topic, but I could not find a clear response.

This is based on the QNA from: javascript - 3D point rotation algorithm - Stack Overflow

enter image description here

My thought was to get the XYZ point and subtract the origin.

From here, multiply the XYZ point by the Rx matrix, take those points and multiply by Ry, and then Rz. Return the point + origin.

This led to the following program:

function rotatePointXYZ(point, origin, rad) {
// Define origin and point axis values
  let ox = origin[0];
  let oy = origin[1];
  let oz = origin[2];
  let px = point[0] - ox;
  let py = point[1] - oy;
  let pz = point[2] - oz;
// rotation on x, y, z
  let tx = rad[0];
  let ty = rad[1];
  let tz = rad[2];
// The transformation matrices.
  let rx = [1, 0, 0, 0, Math.cos(tx), -Math.sin(tx), 0, Math.sin(tx), Math.cos(tx)];
  let ry = [Math.cos(ty), 0, Math.sin(ty), 0, 1, 0, -Math.sin(ty), 0, Math.cos(ty)];
  let rz = [Math.cos(tz), -Math.sin(tz), 0, Math.sin(tz), Math.cos(tz), 0, 0, 0, 1];
// Matrix mutiplication
  let rotatedX = [(rx[0] * px + rx[1] * py + rx[2] * pz), (rx[3] * px + rx[4] * py + rx[5] * pz), (rx[6] * px + rx[7] * py + rx[8] * pz)];
  px = rotatedX[0];
  py = rotatedX[1];
  pz = rotatedX[2];
  let rotatedY = [(ry[0] * px + ry[1] * py + ry[2] * pz), (ry[3] * px + ry[4] * py + ry[5] * pz), (ry[6] * px + ry[7] * py + ry[8] * pz)];
  px = rotatedY[0];
  py = rotatedY[1];
  pz = rotatedY[2];
  let rotatedZ = [(rz[0] * px + rz[1] * py + rz[2] * pz), (rz[3] * px + rz[4] * py + rz[5] * pz), (rz[6] * px + rz[7] * py + rz[8] * pz)];
  px = rotatedZ[0];
  py = rotatedZ[1];
  pz = rotatedZ[2];
  return [px + ox, py + oy, pz + oz]
}

console.log(rotatePointXYZ([1, 1, 1], [0, 0, 0], [Math.PI / 2, Math.PI / 2, 0]))

The issue is that this function is also rotating the coordinate within the z-axis despite the angle of rotation being zero radians.

Red is the origin, Orange is pre-rotation, and yellow is post-rotation.

It seems to rotate on the XY plain correctly.

But is also rotating on the z-axis when it should not:

Is this the correct technique? Is there a mistake in my code?

I may be rotating millions of points at a time, so using a three.js implementation may not be ideal.

The issue is that this function is also rotating the coordinate within the z-axis despite the angle of rotation being zero radians.

If you rotate the point (1, 1, 1) by PI/2 radians in the X and Y axes, the rotated point has a Z component different from 1.

The only way to keep Z = 1 is indeed rotating only around Z axis.

About performance, the reason matrices are used in computer graphics is because they can be combined (by multiplication) and then you have to multiply only one matrix by each one of the million vertices, instead of multiplying the vertex successively by the 3 or more matrices you could have. The key is that they are linear, as you have stated.

1 Like

Thank you for the response, I am still learning matrix math so this project has been interesting.

So I should multiply the point [x,y,z] by the 3d rotation matrix or do I instead fo the entire transformation matrix including scale?

If you want to include rotation + scale you have to multiply the vertex by the combined matrix, that’s all.

1 Like