Rendered at 21:52:13 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
Sharlin 1 days ago [-]
To construct the two vectors spanning a given angle (well, as the article says, one of them can be chosen arbitrarily, the easiest is to just use (1, 0)), you'll of course need trigonometric functions. This is exactly equivalent to how constructing a rotation matrix from an angle requires trigonometric functions, but after that you can rotate how many vectors you like with just dot products, or how constructing e^ai = sin(a) + cos(a)*i requires trigonometric functions, but after that it's just complex multiplication.
Alan Paeth's three-shear rotation is one of my favorite algorithms, especially because it's perfectly suited for rotating pixel art. Because shearing preserves all the original pixels, it even works with dithered images, unlike sampling-based rotation schemes.
It's also fairly simple to implement. I have implemented a version that rotates ASCII art, and that code made it to Ruby's list of sample programs:
Older versions of mspaint had shear but not rotation (to arbitrary angles), and you could use the same approach to achieve rotation via shearing.
ttoinou 1 days ago [-]
Because an "angle" is by definition trigonometric, it's a ratio of a circle perimeter. You can also use an angle already formed by two vectors and won't need trigonometry. You can also use others things than trigonometric angles, such as spread from rational trigonometry
Sharlin 1 days ago [-]
Sure. Point is, this double-reflection construction is in no sense unique in requiring "no trigonometric functions".
ttoinou 12 hours ago [-]
Right, it’s not unique
amitp 6 hours ago [-]
Bookmarked! I love the interactive diagrams! I love that you have a touch-point larger than the drag handle. And I'm impressed that the label placement takes care to avoid the axes. Some feedback:
You have vector s in blue, and then vector u in teal, and then vector v in orange.
In the diagram, it's "Subject", "First Reflector", "Second Reflector". I think it'd be better if these labels were "Subject s", "First Reflector u", "Second Reflector v" so that we can match up the text to the diagram even without color.
Later you have "The pair of vector u and v is called a rotor". But these colors do not match the earlier colors, and it makes it hard to connect to the diagram.
In the 3D diagram, I think it would be better if you used the same color scheme as for the 2D diagram. Same for the circular reflection diagram.
Suggested colors:
- subject s - orange in every diagram (currently blue, blue, blue)
- first reflector - teal in every diagram (currently teal, magenta, pink)
- second reflector - blue in every diagram (currently orange, teal, orange)
This makes the rotor colors more similar to each other than to the subject.
laszlokorte 4 hours ago [-]
Thank you very much! Those are all very good points I agree with.
Reworking the color scheme is something I had already planned.
amluto 1 days ago [-]
The dimension section triggered my “vague math” spider sense:
> During this zic-zac motion across the plane the vector still rotates along the plane in the except same ways as in the 2d case above.
What is “the plane”? In 2D there is one single plane. In 3D every rotation rotated within a 2D plane and preserves the projection of the original vector to the orthogonal complement of the plane (which is just the distance from the plane and which side the original point is on).
In 4D and up, sorry, all of our nice 3D human intuition is wrong. You can rotate in two planes at once, and that’s not equivalent to a rotation in any given plane.
And indeed the article is pretty close to being a proof that the construction doesn’t work in 4+ dimensions. Reflection across a codimension-1 hyperplane (i.e. a n-1-dimension hyperplane) negates a single basis vector. Do two of these and the span of those vectors defines a 2D plane, and you get a rotation in that specific plane and no other. And this is insufficient to describe a general rotation.
Of course, in 4D, there are other sorts of reflection-ish operations, like how in 3D you can negate the x and y coordinates while leaving z alone. (That specific operation is, itself, a rotation and does not change parity!) I think that, if you are willing to appropriately stretch the idea of “reflection”, then you can generate all the rotations in higher dimension.
laszlokorte 18 hours ago [-]
Oh, you are right. My 3d example is bad indeed. Thanks for pointing it out.
I think my mistake from the very beginning was to frame „reflection“ as happening around a vector instead of around a plane. I did this because I thought of it to be easier to vidualize. The I carried it on into 3d but as you say it does not generalize.
Had I started with doing reflections across planes I think it might generalize correctly across dimensions.
I have to admit this kind of mistake might completely undermine the correctness and usefulness of the visualization. I will rework this.
Glad you noticed it.
zkmon 1 days ago [-]
There is no mystery. Imagine a huge radius of rotation. Then a small rotation is almost like a linear shift due to the large radius. Two reflections around a small angle would mean two "half roll-overs" making it a full roll-over. That means you just shifted (rotated) the thing.
kazinator 1 days ago [-]
Note that to reflect a rigid, physical model of a 2D shape, you have to rotate it around the reflection axis in 3D space. I.e. reflection is just a rotation involving a temporarily borrowed extra dimension.
Another fun way to decompose 2D rotation is into three shears, originally given by Paeth in 1986: https://silmon.github.io/arbitrary-image-rotation-using-shea...
It's also fairly simple to implement. I have implemented a version that rotates ASCII art, and that code made it to Ruby's list of sample programs:
https://github.com/ruby/ruby/tree/master/sample/trick2025/01...
You have vector s in blue, and then vector u in teal, and then vector v in orange.
In the diagram, it's "Subject", "First Reflector", "Second Reflector". I think it'd be better if these labels were "Subject s", "First Reflector u", "Second Reflector v" so that we can match up the text to the diagram even without color.
Later you have "The pair of vector u and v is called a rotor". But these colors do not match the earlier colors, and it makes it hard to connect to the diagram.
In the 3D diagram, I think it would be better if you used the same color scheme as for the 2D diagram. Same for the circular reflection diagram.
Suggested colors:
- subject s - orange in every diagram (currently blue, blue, blue)
- first reflector - teal in every diagram (currently teal, magenta, pink)
- second reflector - blue in every diagram (currently orange, teal, orange)
This makes the rotor colors more similar to each other than to the subject.
> During this zic-zac motion across the plane the vector still rotates along the plane in the except same ways as in the 2d case above.
What is “the plane”? In 2D there is one single plane. In 3D every rotation rotated within a 2D plane and preserves the projection of the original vector to the orthogonal complement of the plane (which is just the distance from the plane and which side the original point is on).
In 4D and up, sorry, all of our nice 3D human intuition is wrong. You can rotate in two planes at once, and that’s not equivalent to a rotation in any given plane.
And indeed the article is pretty close to being a proof that the construction doesn’t work in 4+ dimensions. Reflection across a codimension-1 hyperplane (i.e. a n-1-dimension hyperplane) negates a single basis vector. Do two of these and the span of those vectors defines a 2D plane, and you get a rotation in that specific plane and no other. And this is insufficient to describe a general rotation.
Of course, in 4D, there are other sorts of reflection-ish operations, like how in 3D you can negate the x and y coordinates while leaving z alone. (That specific operation is, itself, a rotation and does not change parity!) I think that, if you are willing to appropriately stretch the idea of “reflection”, then you can generate all the rotations in higher dimension.
I think my mistake from the very beginning was to frame „reflection“ as happening around a vector instead of around a plane. I did this because I thought of it to be easier to vidualize. The I carried it on into 3d but as you say it does not generalize.
Had I started with doing reflections across planes I think it might generalize correctly across dimensions.
I have to admit this kind of mistake might completely undermine the correctness and usefulness of the visualization. I will rework this. Glad you noticed it.