Before I explain anything credit for this post goes to my friend Steve at BSS who originally showed me this.
So my goal was to figure out how Papervision initially worked. My first assumption is that people were using the flash.geom.Matrix class to perform perspective transformations on BitmapData, but this is not the case. The Matrix class in Flash is only able to create affine transformations.
First let's take a look at affine transformations:
Affine transformations are transformations where:
- Collinearity between points, i.e., three points which lie on a line continue to be collinear after the transformation
- Ratios of distances along a line, i.e., for distinct colinear points p1,p2,p3, | | p2 − p1 | | / | | p3 − p2 | | is preserved
What We Can Do
What we can do is approximate 3D transformations by approximating a perspective transformation. We'll approximate by slicing our 2D image into smaller pieces and performing transformations on those individual pieces. As a side effect the image may be distorted, but we'll be able to control the distortion if we cut the image into smaller pieces.
Let's experiment through visually. Start with a grid image and slice it into two triangles:
Now let's take a look at two particular affine transformations.
Notice that the pixels near the line P1P4 do not move very much. These are a characteristic natures of these two particular transformations, scale and skew.
So if we take the top portion of the skewed image and the bottom portion of the scale image, it's possible to arrange the image so we're able to move only P4.
Therefore, since our pixels near our slice are able to match up, performing transformations on the individual pieces to allow our lines to converge and we are able to approximate perspective transformations with a certain degree of distortion. For each of the other points we'll simply use the same affine transformations. In my explanation I've only detailed one corner P4.
To reduce the amount of distortion we'll simply create more subdivisions, or tessellations, for some given picture. As the pieces become smaller and smaller the distances between where pixels are and should be become closer and closer.
Here is an example with draggable corners and smoothing:
For those that are interested, we can prove this mathematically because of the way image data is manipulated mathematically by these affine transformations. I'll talk about this next time for the real nerds.