package { /** * ... * @author nicoptere */ import flash.display.BitmapData import flash.geom.Point; public class Homography { /** * performs a homography on a bitmapData given 4 control points * @param bmpd the bitmapData to distort * @param destWidth the homographic swatch's width * @param destHeight the homographic swatch's height * @param p0 first control point * @param p1 second control point * @param p2 third control point * @param p3 fourth control point * @return */ static public function setTransform(bmpd:BitmapData, destWidth:int = 100, destHeight:int = 100, p0:Point = null, p1:Point = null, p2:Point = null, p3:Point = null):BitmapData { if ( p0 == null || p1 == null || p2 == null || p3 == null ) return null; // resolving system var system:Array = getSystem( [ p0, p1, p2, p3 ] ); //creating the destination bitmapData var target:BitmapData = new BitmapData(destWidth, destHeight, true, 0); target.lock(); bmpd.lock(); // assigns each pixel to its new location var i:int; var j:int; var x:Number; var y:Number; var u:Number; var v:Number; var p:Point; for ( i = 0; i < destHeight; i++ ) { x = i; for ( j = 0; j < destWidth; j++) { y = j; p = invert( x/destWidth, y/destHeight, system); target.setPixel32( i, j, bmpd.getPixel32(p.x, p.y) ); } } return target; } static private function getSystem( P:Array ):Array { var system:Array = new Array( 8 ); var sx:Number = (P[0].x-P[1].x)+(P[2].x-P[3].x); var sy:Number = (P[0].y-P[1].y)+(P[2].y-P[3].y); var dx1:Number = P[1].x-P[2].x; var dx2:Number = P[3].x-P[2].x; var dy1:Number = P[1].y-P[2].y; var dy2:Number = P[3].y-P[2].y; var z:Number = (dx1*dy2)-(dy1*dx2); var g:Number = ((sx*dy2)-(sy*dx2))/z; var h:Number = ((sy*dx1)-(sx*dy1))/z; system[0]=P[1].x-P[0].x+g*P[1].x; system[1]=P[3].x-P[0].x+h*P[3].x; system[2]=P[0].x; system[3]=P[1].y-P[0].y+g*P[1].y; system[4]=P[3].y-P[0].y+h*P[3].y; system[5]=P[0].y; system[6]=g; system[7]=h; return system; } static private function invert( u:Number, v:Number, system:Array ):Point { return new Point((system[0]*u + system[1] * v + system[2] ) / ( system[6] * u + system[7]*v+1), (system[3]*u+system[4]*v+system[5])/(system[6]*u+system[7]*v+1) ); } } }