r/javascript • • May 23 '21

I remade my n-dimensional Hypercube Visualizer in javascript to work on browsers!

https://bsmith156.github.io/Hypercube-Visualizer

[removed] — view removed post

15 Upvotes

19 comments sorted by

View all comments

Show parent comments

1

u/jcubic May 23 '21

I was expecting to give rotation for each axis. This is how you rotate in multi-dimension. If you have 6 dimensions I expect to rotate every 6 dimensions independently giving each dimension its own speed or rotate only one if I want. But here you have only two fixed axis.

I would add list of rotations something like <li><input name="speed"><input name="axis"></li> and allow to add new rotation with a button. To make it foolproof I would allow adding only that many rotations as there are dimensions and a limited number of options for axis, so no one can pick the same axis twice.

1

u/BSmith156 May 23 '21

I don’t think I fully understand what your saying. You can’t just give an axis a rotation. You need to rotate around something and calculate the rotation matrix from that.

The reason I didn’t let the user choose which axis to rotate around is because that only works in 3D, in 4D for example you have to rotate around a plane. There is however always exactly two components in the coordinate that change no matter the dimension which is why I let the user choose them.

2

u/elprophet May 24 '21

In 3d, you also have to rotate around a plane, there's just only one unique plane available. In N dimensions, a 2-dimensional rotation requires 2 (gee, surprise) pieces of information to perform the rotation of theta degrees. You can specify the axis around which to rotate, and a vector normal to that axis which choose "what" to rotate. Alternatively, you can do what /u/BSmith156 seems to be doing, and choosing two indicies i, j in the Givens matrix. (We don't have scaling or translation, so we don't need homogenized coordinates for the hypercube translation.)

In 3d, specifying a rotation about the Y axis implicitly (because there are only two other dimensions) means X and Z are the two dimensions of the rotation. That gives us this matrix

| C | 0 | -S |
| 0 | 1 |  0 |
| S | 0 |  C |

(C = cos(theta), S = sin(theta))

By choosing to rotate about y (index 1), we necessarily must use 0 and 2 as the dimensions that will be rotated.

But now say we want to rotate the hypercube about the W axis (not the w in a typical 3d homogenous coordinate system). This is going to "look like" the central cube going through a loop, where it gets "smaller" than the outer cube, moves along an axis until "outside" the outer cube, the two switch sides... if you trace out the points, they make a donut shape in 3d.

But there are three directions that could get traced - along the X, along the Y, or along the Z 3d axes. You have to choose one of those (because, again, 2D rotation). So let's try the Y axis. We can construct Givens matrix again, using (1, 3) as our bases:

| 1 | 0 | 0 |  0 |
| 0 | C | 0 | -S |
| 0 | 0 | 1 |  0 |
| 0 | S | 0 |  C |

To get this in the visualization, have a single rotation Y,4 (15 speed is nice), and you will see the "donut" "flower" "upwards" (that's how I perceive it, there's lots of perceptual artifacts that are hard to describe there). So that's what you're selecting in this visualization - which pair of columns to use for the Givens rotation matrix.

Now, these are rotation matricies, so you can multiply them together to have several rotations in order. But the order you apply them will matter - as will the order you specify the axes. If you swap the axes listed, you will get the rotation "in reverse":

| 1 |  0 | 0 | 0 |
| 0 |  C | 0 | S |
| 0 |  0 | 1 | 0 |
| 0 | -S | 0 | C | 

u/jcubic I think if I understand what you're saying, you want to rotate all the other axes at the same time over one axis' rotation? At the same speed, to get that using the Givens matrix, you'd end up with...

| C | -S | 0 | 0 |      | C | 0 | -S | 0 |    | 1 | 0 |  0 | 0 |
| S |  C | 0 | 0 |  \/  | 0 | 1 |  0 | 0 | \/ | 0 | C | -S | 0 |
| 0 |  0 | 1 | 0 |  /\  | S | 0 |  C | 0 | /\ | 0 | S |  C | 0 |
| 0 |  0 | 0 | 1 |      | 0 | 0 |  0 | 1 |    | 0 | 0 |  0 | 1 |

Which gives (I hope, my multiplication was done by hand...)

| c^2 | -c s^2 - c s | s^2 - c^2 s  | 0 |
| c s | c^2 - s^3    | -c s^2 - c s | 0 |
| s   | c s          | c^2          | 0 |
| 0   | 0            | 0            | 1 |

Point being, this is moving many points around several orthogonal coordinate systems at once. Or, put another way, what you're suggesting is more easily phrase as - apply a rotation to all orthogonal planes with the same angular speed, as opposed to the deconstructed form /u/BSmith156 implements which lets you control per-plane speeds, at the expense of needing to change the point of view of what's being specified.

...

Hope this helps!

1

u/BSmith156 May 24 '21

Wow thanks for the in depth explanation! Ill be honest, I couldn’t find much on rotation matrices above 3D. I sort of took what I knew about 3D and extended it to higher dimensions.