Wednesday, October 31, 2007

Emulating 3D Bitmap Transformations

I've been looking into 3D through Flash and there's a lot of 3D projects going on in the community, but Flash is currently not natively 3D. Though the new upcoming version of Flash seems very promising.
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, | | p2p1 | | / | | p3p2 | | is preserved
This allows us to achieve only an isometric projection. What we are looking for is to be able to create depth using a perspective projection. With perspective we need to create a vanishing point which means lines which means parallel lines can converge. So this is a dilemma.

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.

Controlling Distortion
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:

Verification Mathematically:
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.

Download the source


Kanzo said...

Great work. It is now all clear to me :D

Henry Tseng said...

Great. Keep checking here and making comments. I never know if people actually read this stuff, but I will definitely write more and more if people check this more.

Ezekiel Olayode said...

This is a very interesting code, i have been look around for this.

Thank You so much, you made my day.

Aron said...

how could I add more control points to the image ?

Henry Tseng said...

More controls points are means making subdivisions of the image each with corner points.

Anonymous said...

Hey I'd like to congratulate you for such a terrific made site!
Just thought this is a nice way to make my first post!

Robin Toby
if you're ever bored check out my site!
[url=]bob the builder Party Supplies[/url].

Anonymous said...

Your blog keeps getting better and better! Your older articles are not as good as newer ones you have a lot more creativity and originality now keep it up!

9tontruck said...

Is it possible to apply bi-linear or bi-cubic interpolation during the transformation?