--- title: Spinning spatial cross description: We are writing an algorithm for rotating a three-dimensional figure by an angle around its center along all three axes at once. In the previous example... sections: [Volumetric figures,Rotation matrix,Experimental model] tags: [javascript,canvas,geometry,matrix,graphics,image,picture,square,cube] scripts: [/js/classes-point-cube.js,/js/spinning-spatial-cross.js,/js/spinning-spatial-cross2.js] styles: [/css/pomodoro1.css] canonical_url: /en/2023/01/16/spinning-spatial-cross.html url_translated: /ru/2023/01/15/spinning-spatial-cross.html title_translated: Вращаем пространственный крест date: 2023.01.16 lang: en --- We are writing an algorithm for rotating a three-dimensional figure by an angle around its center along all three axes at once. In the previous example, we [rotated cube in space]({{ '/en/2023/01/11/spinning-cube-in-space.html' | relative_url }}) — now there are a lot of cubes, the algorithm is almost the same and we use the same formulas. We draw two variants of the figure: *spatial cross* and *cross-cube* in two types of projections, consider the difference. Testing the experimental interface: [Volumetric tetris]({{ '/en/2023/01/22/volumetric-tetris.html' | relative_url }}). ## Spatial cross {#spatial-cross}
Parallel projection

Your browser does not support Canvas

Perspective projection

Your browser does not support Canvas

## Cross-cube {#cross-cube}
Parallel projection

Your browser does not support Canvas

Perspective projection

Your browser does not support Canvas

*Parallel projection* — all cubes are the same size. *Perspective projection* — the cubes look shrinking in the distance. ## Experimental model {#experimental-model} Slightly complicated version from the previous example — now there are a lot of cubes. In addition to the previous settings there can be changed: figure variant — *spatial cross* or *cross-cube*, face sorting direction — *linear perspective* or *reverse perspective* and transparency of the cube walls.

Your browser does not support Canvas

Rotation around axes:
Center onto observer screen:
150
150
125
Remoteness of projection center:
300
Transparency of cubes:
20%
Variant of the figure:
Perspective projection:
## Algorithm description {#algorithm-description} We prepare a matrix of zeros and ones, where one means a cube in a certain place of the figure. Then we bypass this matrix and fill in the array of cubes with the corresponding coordinates of the vertices. After that, we start the rotation along all three axes at once. At each step, we bypass the array of cubes and get projections of their faces. Then we sort the array of faces by remoteness from the projection center, bypass this array and throw away the same pairs from it — these are the adjacent walls between neighboring cubes inside the figure. After that we draw cube faces with a translucent color — first the distant and then the near ones, so that the distant faces can be seen through the near ones. ## Implementation in JavaScript {#implementation-in-javascript} {% include classes-point-cube-en.md -%} Create objects according to templates and draw their projections on the plane. ```js 'use strict'; // matrices-templates for cubes const shape1 = [ // spatial cross [[0,0,0,0,0], [0,0,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]], [[0,0,0,0,0], [0,0,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]], [[0,0,1,0,0], [0,0,1,0,0], [1,1,1,1,1], [0,0,1,0,0], [0,0,1,0,0]], [[0,0,0,0,0], [0,0,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]], [[0,0,0,0,0], [0,0,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]]]; const shape2 = [ // cross-cube [[0,0,1,0,0], [0,0,1,0,0], [1,1,1,1,1], [0,0,1,0,0], [0,0,1,0,0]], [[0,0,1,0,0], [0,0,0,0,0], [1,0,0,0,1], [0,0,0,0,0], [0,0,1,0,0]], [[1,1,1,1,1], [1,0,0,0,1], [1,0,0,0,1], [1,0,0,0,1], [1,1,1,1,1]], [[0,0,1,0,0], [0,0,0,0,0], [1,0,0,0,1], [0,0,0,0,0], [0,0,1,0,0]], [[0,0,1,0,0], [0,0,1,0,0], [1,1,1,1,1], [0,0,1,0,0], [0,0,1,0,0]]]; // cube size, number of cubes in a row, indent const size = 40, row = 5, gap = 50; // arrays for cubes const cubes1 = [], cubes2 = []; // bypass the matrices, fill the arrays with cubes for (let x=0; xMath.abs(b.dist-a.dist)>size ? b.dist-a.dist : b.clock-a.clock); // sort the faces by remoteness from the projection center perspective.sort((a,b)=>b.dist-a.dist); // draw parallel projection drawFigure(cnv1, parallel); // draw perspective projection drawFigure(cnv2, perspective); } ``` ```js // do not draw adjacent walls between neighboring cubes function noAdjacent(array) { // sort the faces by remoteness array.sort((a,b) => b.dist-a.dist); // remove the adjacent walls between cubes for (let i=0, j=1; isetInterval(repaint,50)); ```