Rotation with three shears
cohost.org
cohost.org
At the time I was attempting to use standard open source image processing software like ImageMagick to manipulate scientific data. I was disappointed to find that it was not suitable, both due to approximations like this one, and because all the libraries I looked at only allowed 8-bit grayscale. I really wanted floating point data.
Here is what I was working on back in those days: https://www.ocf.berkeley.edu/~fricke/projects/israel/project...
I was a summer student at the Weizmann Institute of Science in Rehovot, Israel, processing electron micrographs of a particular protein structure made by a particular bacterium. It's very interesting: this bacterium attacks plants and injects some genetic material into the plant, causing the plant to start manufacturing food for the bacterium. By replacing the "payload" of this protein structure, the mechanism can be used to insert other genetic structures into the plant, instead of the sequence that causes it to produce food for the bacterium. Or something like that.
Here's a random chunk of my research journal from those days: https://www.ocf.berkeley.edu/~fricke/projects/israel/journal...
The work contributed to this paper: https://www.jbc.org/article/S0021-9258(20)66439-0/fulltext
Here's the Wikipedia article about the author of that algorithm: https://en.wikipedia.org/wiki/Alan_W._Paeth
And his original web page that I linked to, now via archive.org: https://web.archive.org/web/20050228223159/http://people.ouc...
If you liked this trick, check out Alan Paeth's "Graphics Gems" series of books.
Kudos and thanks to the OCF at UC Berkeley which has hosted my web page there for more than a quarter century with just about zero maintenance on my part.
And thanks for the trip down memory lane!
It seems that this algorithm was independently discovered by several authors, some of them earlier than Paeth's:
* H.Kiesewetter, A.Graf, Rotation in Digital Grids and Corresponding Models, Tech. Rep. Zentralinstitut für Kybernetik und Informationsprozesse, Akademie de Wissenschaften der DDR, 1985
* A.W.Paeth, A fast algorithm for general raster rotation, Proceedings GIVIP 1986
* P.E.Danielsson, M.Hammerin, High-accuracy rotation of images, CVGIP: Graphical Models and Image Processing, 1992.
And this algorithm was implemented on the image package of the ICL Distributed Array Processor [0] as soon as 1984.
The most cited reference for this method seems to be the famous "Yaroslavski" rotation:
* M.Unser, P.Thevenaz, L.Yaroslavski, Convolution-Based Interpolation for Fast, High-Quality Rotation of Images, IEEE Trans. Image Processing 1995
This is the same method but the shears are computed as filters in the frequency domain, thus they are exactly invertible (which is not the case if you use splines to perform the shears). Here the method really shines: you can rotate 36 times by 10 degrees and get back to the initial image, which is really spectacular.
I wouldn't be surprised if the decomposition itself was a well-known older result in linear algebra, for it seems to be closely related to the QR factorisation.
[0] https://en.wikipedia.org/wiki/ICL_Distributed_Array_Processo...
So you have a system like this to solve:
[[1,a],[0,1]]*[[1,0],[b,1]]*[[1,c],[0,1]]
== [[cos q, -sin q],[sin q, cos q]]
It's not hard to solve (despite being overdetermined) and you can even throw that line above into a CAS directly. The solution is a bit long to paste here though.Did you try ImageJ (https://imagej.net/)? I think it had support for floating point data 20 years ago. It also can be extended through plug-ins, so if it lacked a feature, it could be added fairly cleanly.
Back in those days, game programmers were like wizards. They did some pretty awesome stuff, with terrible toolsets.
They also tended to be paid fairly poorly, and worked to death, if I remember. I was once recruited by Sierra Online, and decided that discretion was the better part of valor, and all that.
When you went to his classes you really had no idea what it was going to be about. I got the sense that sometimes he would just teach whatever was on his mind that day, nevermind the syllabus. It was sometimes bizarre, often challenging, and always interesting. I learned a lot from him.
I'm sad that he has passed and sorry to see his website is no longer online, but also pleased that his legacy is living on and people other than me still think of him -- thank you!
- If the two lines we're reflecting across meet at a point, we'll get a rotation around that point (with twice the angle between the lines)
- If the two lines are parallel, we'll get a translation (perpendicular to the lines, of twice the distance between the lines)
In projective geometry (where parallel lines "meet at infinity"), rotation and translation are the same thing.
There's also a link to geometric algebra, which composes reflections into arbitrary "rotors"/"motors" (which are the same thing, projectively). To transform an object with a rotor, we apply it twice; due to this underlying 'two reflections' behaviour.
(Demo: https://enkimute.github.io/ganja.js/examples/coffeeshop.html... )
I think using that in a voxel editor would be very useful.
I remember a college exercise where I had to prove this by calculating the resulting transformation matrix which would apply these three shears in order and comparing it to the rotation matrix as provided.
Similarly, translation in 2D is the same as shearing in 3D - and translating in 3D is the same as shearing in 4D. That's why a lot of game engines use a 4D matrix for, well, everything: it's a very convenient way to scale, orient, and position an object.
Takes a while to get used to - especially if you have never used matrices before - but they are actually really easy in practice.
Edit: Actually, I suppose the minimum stretch was 1%. So the square should be 100x100 in size :)
1. Enlarge image by 200% -- mspaint uses nearest neighbor interpolation so this turns every pixel into 4 with no smoothing.
2. Replace every second row with a gnarly pink color, or anything else that's not in your original picture. Kinda tedious but with copy paste you can do it pretty fast.
3. Set that pink as your background color, then use the "transparent select" or whatever, it will select all pixels in your rectangle that's not your current background color.
4. Enlarge the target image by 200% in another mspaint, copy the first image over, then shrink by 50%.
I loved doing that haha, showed it to all my nerd friends.
Has links to two detailed blog posts about the method.
I can't think of any games console hardware which allowed a combination of more than two shears by modification of sprite/bg offset registers, it was either X, Y, or X+Y, but not X+Y+X.
It seems to me that using dx+dy 8.8 or 16.16 fixed-point coefficients for an inverted rotation matrix would by faster in terms of only one read+write required per pixel, rather than multiple (at least that's how I always saw rotations in the VGA mode 13h days, maybe things like the Amiga blitter could do it better?).
https://www.sega-16.com/forum/archive/index.php/t-21390.html
If you think about these mrhtods using physics, it's extremely frustrating because nothing actually rotates. At the first detail, each pixel is facing the same direction. This is fine for discrete pixels, but feels wrong. Is it valid in real physics? Do the smallest particles have orientation?
(disclaimer: I'm not a hardware guy, and I also don't know if this applies to all pixel formats and different GPU architectures - texture cache details are also notoriously bad documented by GPU vendors).
Maybe you could run them like an ensemble model. All randomness in every game unique and user input delayed by 0-25ms on all of them. Instead of losing a life you lose a parallel copy, specifically one of the ones you died in.
The display shows them overlaid all at once.
The paddle would be a tetris field, so you'd be playing that as usual, but also moving it up and down to bounce the ball.
The idea of putting games inside each other like that appealed for a while. I could imagine running snake inside the "dots" of pacman, and other simple things for example.
Controlling them would be a nightmare, but it's a fun experiment to imagine the games that would go well inside each other. Defender in the logs floating in frogger, for example?
"Obvious" means you know it without thinking.
Not everything pans out the way even the best think - and the very best are notorious for "knowing" results in a flash .. but having to diddle about to produce a logical chain that "proves" that flash for minute, hours, days and sometimes years or a century after their death..
Fractal surface areas, the re-order of terms in an infinte series, infinite hotel questions, etc. were all high school puzzles in the 80s in my part of remote Australia so I can't imagine them stumping or confusing a university math lecturer.