Visualising and Rotating a Matrix

How do I rotate a matrix 90 degrees counterclockwise in java?

If you draw out the matrix to visualize, you'll see that some of your indices are off. For example, instead of using matrix.length-1, you should use bottom in your updates because the size of the layer's square will decrease as i increases. Another error is that in your second update, you should have:

matrix[j][bottom] = matrix[bottom][bottom - (j - top)];

instead of:

matrix[j][bottom] = matrix[bottom][j];

This is because in the bottom row of the layer the indices start from the last column and move backward to the first column. j - top indicates how far along you are in the top row of your layer.
After drawing out the matrix, I found the correct updates to be as follows:

public static void main(String[] args) {
int n = 5;
int[][] a = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = i * n + j + 1;
}
}
rotateMatrix(a);
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
System.out.printf("%3d", a[i][j]);
}
System.out.println();
}
}
public static void rotateMatrix(int[][] matrix) {
if (matrix.length == 0) {
return;
}
for (int i = 0; i < matrix.length / 2; i++) {
int top = i;
int bottom = matrix.length - 1 - i;
for (int j = top; j < bottom; j++) {
int temp = matrix[top][j];
matrix[top][j] = matrix[j][bottom];
matrix[j][bottom] = matrix[bottom][bottom - (j - top)];
matrix[bottom][bottom - (j - top)] = matrix[bottom - (j - top)][top];
matrix[bottom - (j - top)][top] = temp;
}
}
}

Output:

5 10 15 20 25
4 9 14 19 24
3 8 13 18 23
2 7 12 17 22
1 6 11 16 21

3D point rotation algorithm

A rotated vector can be described as a product of a rotation matrix with that vector. The German Wikipedia page on pitch, roll and yaw describes the rotation matrix for given Euler rotation angles.

With that information, the rotation of all points with the same angles can be written as JavaScript function, where the points array is global:

function rotate(pitch, roll, yaw) {
var cosa = Math.cos(yaw);
var sina = Math.sin(yaw);

var cosb = Math.cos(pitch);
var sinb = Math.sin(pitch);

var cosc = Math.cos(roll);
var sinc = Math.sin(roll);

var Axx = cosa*cosb;
var Axy = cosa*sinb*sinc - sina*cosc;
var Axz = cosa*sinb*cosc + sina*sinc;

var Ayx = sina*cosb;
var Ayy = sina*sinb*sinc + cosa*cosc;
var Ayz = sina*sinb*cosc - cosa*sinc;

var Azx = -sinb;
var Azy = cosb*sinc;
var Azz = cosb*cosc;

for (var i = 0; i < points.length; i++) {
var px = points[i].x;
var py = points[i].y;
var pz = points[i].z;

points[i].x = Axx*px + Axy*py + Axz*pz;
points[i].y = Ayx*px + Ayy*py + Ayz*pz;
points[i].z = Azx*px + Azy*py + Azz*pz;
}
}

Most of that is setting up the rotation matrix as described in the article. The last three lines inside the loop are the matrix multiplication. You have made a point of not wanting to get into matrices, but that's hardly intimidating, is it? Sooner or later you will encounter more matrices and you should be prepared to deal with them. The stuff you need – multiplication, mainly – is simple. The more complicated stuff like inverting matrices is not needed for your requirements.

Anyway, that performs reasonably fast for 300,000 points. I was able to rotate a point cloud of that size and render it on a 1000px × 1000px canvas in about 10ms.

How to use a matrix to rotate the reference system of a vector relatively to another?

One simpler answer that comes to mind is to use cross products.

you can find east with Ve = Va ⨉ Vm
and then north with Vn = Va ⨉ Ve

(this might actually be south, haven't thought through the handedness)



Related Topics



Leave a reply



Submit