Check it out − curved text in Flash! And it is totally editable, too − you just click and type whatever you want there. This was done as a part of lightspeedsigns.com. Some people thought it wasn't possible... But not with me :)
So, how hard was it to make something like that? Not hard at all! The math behind this example is so easy that a schoolgirl could do it.
Here is what needs to be done. Start with map code stub I gave you before. Calculate circle center (and radius):
// tweak K to move a center var K = 1.65, xK = w/2, yK = K * h;
Now, calculate key elements of layout geometry. In CDG triangle, you already know that CG = BG = yK and CD = xK. This gives you unknown side, DG, and angle, LCGD. Note that CDG is similar to EFG, and FG = BG - BF = yK - h. This gives you unknown side, EG. You have now half of work done.
The rest is straightforward. For every L (x, y), calculate angle LNGL and lineary map it to source rectangle: xS = w · LNGL / LNGM (note that angle LNGM = 2 · LCGD that you've found above), and yS = h · CN / CE = h · (yK - LG) / (yK - EG). Now your code should look somewhat like this:
import flash.display.BitmapData;
// BitmapData to hold the map
var map:BitmapData = new BitmapData (256, 128, true),
w:Number = map.width, h:Number = map.height;
// tweak K to move a center
var K = 1.65, xK = w/2, yK = K * h;
// key elements
var DG = Math.sqrt (yK * yK - xK * xK);
var CGD = Math.acos (DG / yK);
var EG = yK * (yK - h) / DG;
// color factors
var af = 16777216, rf = 65536, gf = 256, bf = 1;
// this may take a while
for (var x:Number = 0; x < w; x++)
for (var y:Number = 0; y < h; y++) {
// angle and distance for (x, y)
var LG = Math.sqrt ((x - xK) * (x - xK) + (y - yK) * (y - yK));
var NGL = CGD + Math.asin ((x - xK) / LG);
// set source pixel coordinates for (x,y)
var xS:Number = Math.round (w * NGL / (2 * CGD));
var yS:Number = Math.round (h * (yK - LG) / (yK - EG));
// calculate & store displacement in B & G channels
map.setPixel (x, y, bf * (128 + xS - x) + gf * (128 + yS - y));
}
// show the result: make the screenshot, crop it, and import
_root.attachBitmap (map, _root.getNextHighestDepth ());
That wasn't that bad, was it? Now when you've made a map, go bend something. Have fun.