In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

画像変形処理の練習

Get Adobe Flash player
by termat 10 Apr 2010
    Embed
/**
 * Copyright termat ( http://wonderfl.net/user/termat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/xGI8
 */

package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import com.bit101.components.*;
	
	[SWF(width = "480", height = "480", backgroundColor = "0xffffff",frameRate="60")] 
	public class Practice53 extends Sprite {
		private var canvas:Canvas;
		
		public function Practice53() {
			canvas = new Canvas();
			canvas.x = 40;
			canvas.y = 40;
			addChild(canvas);
			var prob1 : RadioButton = new RadioButton(this, 10, 5, "Source", true, function(e:Event):void { canvas.setSource(); } );
			var prob2 : RadioButton = new RadioButton(this, 70, 5, "Corn", false, function(e:Event):void { canvas.setCorn(); } );
			var prob3 : RadioButton = new RadioButton(this, 130, 5, "Sphere", false, function(e:Event):void { canvas.setSphere(); } );
			var prob4 : RadioButton = new RadioButton(this, 190, 5, "Cyrinder", false, function(e:Event):void { canvas.setCyrinder(); } );
			var prob5 : RadioButton = new RadioButton(this, 250, 5, "Fan", false, function(e:Event):void { canvas.setFan(); } );
		}
	}
}
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.MovieClip;
class Canvas extends MovieClip {
	private var bmp:BitmapData;
	private var img:Bitmap;
	private var trans:TransformImage;
	
	public function Canvas():void {
		trans = new TransformImage();
		bmp = new BitmapData(400, 400, false, 0xffffff);
		drawBase();
		img = new Bitmap(bmp);
		addChild(img);
	}
	
	public function setSource():void {
		img.bitmapData = bmp;
	}
	
	public function setFan():void {
		img.bitmapData = trans.fanMapping(bmp, bmp.width, bmp.height, 0xffffff, false, 200, 400, 0, 100, 0.2);
	}
	
	public function setSphere():void {
		img.bitmapData = trans.circleMapping(bmp, bmp.width, bmp.height, 0xffffff, false);
	}
	
	public function setCyrinder():void {
		img.bitmapData = trans.cylinderMapping(bmp, bmp.width, bmp.height, 0xffffff, false);
	}
	
	public function setCorn():void {
		img.bitmapData = trans.coneMapping(bmp, bmp.width, bmp.height, 0xffffff, false);
	}
	
	private function drawBase():void {
		var i:int = 0;
		bmp.fillRect(bmp.rect,0xffffff);
		for (var x:int = 1; x <= bmp.width; x++) {
			for (var y:int = 0; y <= bmp.height; y++) {
				if (i % 2 == 0)	bmp.setPixel(x-1, y, 0x0000ff);
			}
			if (x % 10 == 0) i++;
		}
	}
}

class TransformImage {
	
	public function fanMapping(bmp:BitmapData, width:int, height:int, bcol:uint, t:Boolean,ox:int,oy:int,xx:int,yy:int,rate_r:Number):BitmapData {
		var ret:BitmapData = new BitmapData(width, height, t, bcol);
		var th:Number,r:Number;
		var rx1:int = 0, ry1:int = 0;
		var rx2:int = bmp.width - 1;
		var ry2:int = bmp.height - 1;
		var x1:int = xx, y1:int = yy;
		var x2:int = ox + (ox - xx);
		var y2:int = yy, x3:int = ox, y3:int = oy;
		var rrr:Number = getR(x1, y1, ox, oy);
		var th1:Number = getAngleP(x1, y1, ox, oy);
		var th2:Number = getAngleP(x2, y2, ox, oy);
		var sx:int = Math.min(x1, x2, x3);
		var sy:int = Math.min(y1, y2, y3);
		var ex:int = Math.max(x1, x2, x3);
		var ey:int = Math.max(y1, y2, y3);
		var tth2:Number, th_rate:Number;
		if (th2 < th1) {
			tth2 = th2 + (Math.PI * 2);
		}else {
			tth2 = th2;
		}
		th_rate = tth2 - th1;
		if (th1 < 0 && tth2 > 0)sy = y3 - (rrr + 0.9);
		if (tth2 > Math.PI * 2.0)sy = y3 - (rrr + 0.9);
		if (th1 < (Math.PI / 2.0) && tth2 > (Math.PI / 2.0))ex = x3 + (rrr + 0.9);
		if (tth2 > (Math.PI * 5.0 / 2.0)) ex = x3 + (rrr + 0.9);
		if (th1 < Math.PI && tth2 > Math.PI)ey = y3 + (rrr + 0.9);
		if (tth2 > Math.PI) ey = y3 + (rrr + 0.9);
		if (th1 < -(Math.PI / 2.0) && tth2 > -(Math.PI / 2.0))sx = x3 - (rrr + 0.9);
		if (tth2 > (Math.PI * 3.0 / 2.0)) sx = x3 - (rrr + 0.9);
		var w1:int = (rx2 - rx1 + 1);
		var h1:int = (ry2 - ry1 + 1);
		for (var y:int = sy; y <= ey; y++) {
			for (var x:int = sx; x <= ex; x++) {
				th = getAngle((x - x3), (y - y3));
				if ((th1 > 0.0 || tth2 > 0.0) && th < th1) th += (Math.PI * 2);
				th -= th1;
				th /= th_rate;
				r = getR(x, y, ox, oy);
				r /= rrr;
				r -= rate_r;
				r /= (1.0 - rate_r);
				var fx:Number = th * w1 + rx1;
				var fy:Number = (1.0 - r) * h1 + ry1;
				var col:uint = interpolate(bmp, fx, fy);
				if (col != 0) {
					ret.setPixel(x, y,col);
				}else {
					ret.setPixel(x, y, bcol);
				}
			}
		}
		return ret;
	}
	
	private function getAngle(dx:Number, dy:Number):Number {
		var th:Number;
		if(dy==0.0) {
			if(dx<0.0){
				th = -Math.PI / 2.0;
			}else{
				th = Math.PI / 2.0;
			}
		}else {
			th = Math.atan(dx / -dy);
			if (dy > 0.0) {
				if (dx == 0.0) th = Math.PI;
				if (dx < 0.0) th = th - Math.PI;
				if (dx > 0.0) th = th + Math.PI;
			}
		}
		return th;
	}
	
	private function getAngleP(x1:int, y1:int, ox:int, oy:int):Number {
		var dx:Number = (x1 - ox);
		var dy:Number = (y1 - oy);
		return getAngle(dx,dy);
	}
	
	private function getR(x:int,y:int,x1:int,y1:int):Number{
		var dx:Number = (x - x1);
		var dy:Number = (y - y1);
		return Math.sqrt(dx * dx + dy * dy);
	}
	
	public function circleMapping(bmp:BitmapData, width:int, height:int, bcol:uint, t:Boolean):BitmapData {
		var ret:BitmapData = new BitmapData(width, height, t, bcol);
		var theta:Number;
		var x1:int = 0;
		var y1:int = 0;
		var x2:int = width - 1;
		var y2:int = height - 1;
		var rx1:int = 0;
		var ry1:int = 0;
		var rx2:int = bmp.width - 1;
		var ry2:int = bmp.height - 1;
		var tx1:Number = x1;
		var ty1:Number = y1;
		var tx2:Number = x2;
		var ty2:Number = y2;
		var aa:Number = (ty2 - ty1) / 2.0;
		var a2:Number = aa * aa;
		var bb:Number = (tx2 - tx1) / 2.0;
		var cc:Number = (ry2 - ry1) / 2.0;
		var dd:Number = (rx2 - rx1) / 2.0;
		var toy:Number = (ty2 + ty1) / 2.0;
		var tox:Number = (tx2 + tx1) / 2.0;
		var foy:Number = ((ry2 + ry1)) / 2.0;
		var fox:Number = ((rx2 + rx1)) / 2.0;
		for (var y:int = y1; y <= y2; y++) {
			for (var x:int = x1; x <= x2; x++) {
				var xx:Number = aa * (x - tox) / bb;
				var yy:Number = y - toy;
				var rr:Number = Math.sqrt(xx * xx + yy * yy);
				if (rr <= aa) {
					var vx:Number = getVorg(yy, xx, aa);
					var vy:Number = getVorg(xx, yy, aa);
					var fx:Number = vx * dd + fox;
					var fy:Number = vy * cc + foy;
					ret.setPixel(x, y, interpolate(bmp, fx, fy));
				}else {
					ret.setPixel(x,y,bcol);
				}
			}
		}
		return ret;
	}
	
	private function getVorg(x:Number,y:Number,r:Number):Number{
		if(y==0.0) {
			vy=0.0;
		}else {
			var rt:Number=(r*r-x*x)/(y*y);
			var vy:Number=1.0/Math.sqrt(rt);
			if(y<0.0) vy= -vy;
		}
		return vy;
	}
	
	public function cylinderMapping(bmp:BitmapData, width:int, height:int, bcol:uint, t:Boolean):BitmapData {
		var ret:BitmapData = new BitmapData(width, height, t, bcol);
		var theta:Number;
		var x1:int = 0;
		var y1:int = 0;
		var x2:int = ret.width - 1;
		var y2:int = ret.height - 1;
		var rx1:int = 0;
		var ry1:int = 0;
		var rx2:int = bmp.width - 1;
		var ry2:int = bmp.height - 1;
		var w1:int = rx2 - rx1 + 1;
		var h1:int = ry2 - ry1 + 1;
		var w2:int = x2 - x1 + 1;
		var h2:int = y2 - y1 + 1;
		var ro:Number = w2 / 2.0;
		for (var y:int = y1; y <= y2; y++) {
			for (var x:int = x1; x <= x2; x++) {
				var ww:Number = (x - x1);
				if(ro-ww != 0.0){
					theta=Math.atan(Math.sqrt(2.0*ro*ww-ww*ww)/(ro-ww));
				}else {
					theta = Math.PI / 2.0;
				}
				if(theta<0.0) theta +=Math.PI;
				var fx:Number = (theta * w1) / Math.PI + rx1;
				var fy:Number = (y - y1) * h1 / h2 + ry1;
				ret.setPixel(x, y, interpolate(bmp, fx, fy));
			}
		}
		return ret;
	}
	
	public function coneMapping(bmp:BitmapData, width:int, height:int, bcol:uint, t:Boolean):BitmapData {
		var ret:BitmapData = new BitmapData(width, height, t, bcol);
		var theta:Number;
		var x1:int=0;
		var y1:int=0;
		var x2:int = width - 1;
		var y2:int = height - 1;
		var rx1:int=0;
		var ry1:int=0;
		var rx2:int = bmp.width - 1;
		var ry2:int = bmp.height - 1;
		var w1:int = rx2 - rx1 + 1;
		var h1:int = ry2 - ry1 + 1;
		var w2:int = x2 - x1 + 1;
		var h2:int = y2 - y1 + 1;
		var wh:Number = w2 / 2.0;
		for (var y:int = y1; y <= y2; y++) {
			var ro:Number = (y - y1) / h2 * wh;
			var xs:int = (wh - ro) + x1;
			var xe:int = (wh + ro) + x1;
			for (var x:int = x1; x <= x2; x++) {
				if(x>=xs && x<=xe) {
					var ww:Number = x - xs;
					if(ro-ww != 0.0){
						theta = Math.atan(Math.sqrt(2.0 * ro * ww - ww * ww) / (ro - ww));
					}else{
						theta = Math.PI / 2.0;
					}
					if (theta < 0.0) theta += Math.PI;
					var fx:Number = (theta * w1) / Math.PI + rx1;
					var fy:Number = (y - y1) * h1 / h2 + ry1;
					ret.setPixel(x, y, interpolate(bmp, fx, fy));
				} else {
					ret.setPixel(x, y, bcol);
				}
			}
			for(x=x1;x<=x2;x++) {
				ww=Math.floor(x-x1);
				if(ro-ww != 0.0){
					theta=Math.atan(Math.sqrt(2.0*ro*ww-ww*ww)/(ro-ww));
				}else{
					theta = Math.PI / 2.0;
				}
				if (theta < 0.0) theta += Math.PI;
				fx=(theta*w1)/Math.PI+rx1;
				fy=(y-y1)*h1/h2+ry1;
			}
		}
		return ret;
	}

	private function linarInterpolate(c1:Number,c2:Number,c3:Number,c4:Number,xr:Number,yr:Number):int{
		var d:Number = c1 * (1.0 - xr) + c3 * xr;
		var e:Number = c2 * (1.0 - xr) + c4 * xr;
		var f:Number = d * (1.0 - yr) + e * yr;
		var res:int = Math.floor(f + 0.5);
		return Math.min(255, Math.max(0, res));
	}
	
	private function interpolate(bmp:BitmapData, x:Number, y:Number):uint {
		var px:int = Math.floor(x);
		var py:int = Math.floor(y);
		var xrate:Number = x - px;
		var yrate:Number = y - py;
		var c1:Array = getRGB(bmp.getPixel(px, py));
		var c2:Array = getRGB(bmp.getPixel(px, py + 1));
		var c3:Array = getRGB(bmp.getPixel(px + 1, py));
		var c4:Array = getRGB(bmp.getPixel(px + 1, py + 1));
		var r:int = linarInterpolate(c1[0], c2[0], c3[0], c4[0], xrate, yrate);
		var g:int = linarInterpolate(c1[1], c2[1], c3[1], c4[1], xrate, yrate);
		var b:int = linarInterpolate(c1[2], c2[2], c3[2], c4[2], xrate, yrate);
		return (r << 16) + (g << 8) + b;
	}
	
	private function getRGB(c:uint):Array {
		return [(c & 0xff0000) >> 16, (c & 0xff00) >> 8, c & 0xff];
	}
}