Bitmap perspective transform PerspectiveTransform
Last Update:2017-01-13
Source: Internet
Author: User
Package com. vincent. utils {
Import flash. display .*;
Import flash. geom .*;
Import flash. events .*;
Public class PerspectiveTransform extends Sprite {
Private var photo: Sprite;
Private var tempMc: Sprite;
Private var bitmapSource: BitmapData;
Var showLine = true;
Var inBitmapWidth;
Var inBitmapHeight;
Var bitmapWidth;
Var bitmapHeight;
// When the mouse is pressed, bitmap's transformation range
Var bitmapMtrx = new Matrix ();
Var subBitmapMtix = new Matrix ();
// Stage width variable declaration
Var StWidth = 550;
Var StHeight = 400;
Var ox;
Var oy;
// Focal length
Var focus = 80;
// Camera angle variable
Var angU = 0;
Var angV = 0;
// Number of segments
Var subdiv = 5;
Var subdivPic;
Var subdivVy = new Array ();
Var subdivVx = new Array ();
Var subdivVz = new Array ();
Var subdivX = new Array ();
Var subdivY = new Array ();
Var subdivEnable = new Array ();
Var mtrx = new Array ();
Var mtrx2 = new Array ();
// Segment bitmap's X and Y in the map.
Var subdivMapX = new Array ();
Var subdivMapY = new Array ();
Var subdivWidth;
Var subdivHeight;
Var mtrxSx;
Var mtrxSy;
Var mtrxSxy;
Var mtrxSyx;
Var subdivV;
Var mtrxA;
Var mtrxB;
Var mtrxC;
Var mtrxD;
Var mtrx2A;
Var mtrx2B;
Var mtrx2C;
Var mtrx2D;
Var cos_angU = Math. cos (angU );
Var sin_angU = Math. sin (angU );
Var cos_angV = Math. cos (angV );
Var sin_angV = Math. sin (angV );
Var dx;
Var dy;
Public function PerspectiveTransform (sour: Bitmap ){
This. bitmapSource = sour. bitmapData;
InBitmapWidth = 1/bitmapSource. width;
InBitmapHeight = 1/bitmapSource. height;
BitmapWidth = bitmapSource. width;
BitmapHeight = bitmapSource. height;
Ox = StWidth/2;
Oy = StHeight/2;
SubdivPic = subdiv * (subdiv-1 );
SubdivWidth = bitmapSource. width/(subdiv-1 );
SubdivHeight = bitmapSource. height/(subdiv-1 );
MtrxSx = subdivWidth/bitmapWidth;
MtrxSy = subdivHeight/bitmapHeight;
MtrxSxy = subdivWidth/bitmapHeight;
MtrxSyx = subdivHeight/bitmapWidth;
SubdivV = subdiv-1;
Photo = new Sprite ();
TempMc = new Sprite ();
DrawRec (photo, 0, 0, 0xff0000, 1 );
AddChild (photo );
DrawRec (tempMc, 600,600, 0xffcc00,. 02 );
AddChild (tempMc );
Init ();
}
Private function init (): void {
For (var I = 0; I <subdiv; I ++ ){
For (var j = 0; j <subdiv; j ++ ){
SubdivMapX. push (j * subdivWidth );
SubdivMapY. push (I * subdivHeight );
}
}
//
For (var h = 0; h <subdivPic; h ++ ){
Mtrx. push (new flash. geom. Matrix ());
Mtrx2.push (new flash. geom. Matrix ());
SubdivVy. push (new Array (subdivPic ));
SubdivVx. push (new Array (subdivPic ));
SubdivVz. push (new Array (subdivPic ));
SubdivX. push (new Array (subdivPic ));
SubdivY. push (new Array (subdivPic ));
SubdivEnable. push (new Array (subdivPic ));
}
For (var m = 0; m <subdiv-1; ++ m ){
For (var n = 0; n <subdiv-1; ++ n ){
Var subID = n + m * subdiv;
Var mtrxTx = subdivMapX [subdiv * m + n];
Var mtrxTy = subdivMapY [subdiv * m + n];
Mtrx [subID]. tx = mtrxTx;
Mtrx [subID]. ty = mtrxTy;
Mtrx [subID]. a = mtrxSx;
Mtrx [subID]. B = 0;
Mtrx [subID]. c = mtrxSxy;
Mtrx [subID]. d = mtrxSy;
Mtrx [subID]. invert ();
Mtrx2 [subID]. tx = mtrxTx;
Mtrx2 [subID]. ty = mtrxTy;
Mtrx2 [subID]. a = mtrxSx;
Mtrx2 [subID]. B = mtrxSyx;
Mtrx2 [subID]. c = 0;
Mtrx2 [subID]. d = mtrxSy;
Mtrx2 [subID]. invert ();
}
}
MtrxA = mtrx [0].;
MtrxB = mtrx [0]. B;
MtrxC = mtrx [0]. c;
MtrxD = mtrx [0]. d;
Mtrx2A = mtrx2 [0].;
Mtrx2B = mtrx2 [0]. B;
Mtrx2C = mtrx2 [0]. c;
Mtrx2D = mtrx2 [0]. d;
Photo. graphics. clear ();
TempMc. addEventListener (MouseEvent. MOUSE_DOWN, onMouseDownHandler );
TempMc. addEventListener (MouseEvent. MOUSE_UP, onMouseUpHandler );
Fun6 (, 0,-, 0,-1 );
Render ();
}
Private function onMouseDownHandler (evt: MouseEvent): void {
TempMc. addEventListener (Event. ENTER_FRAME, onEnterFrameHandler );
Dx = mouseX;
Dy = mouseY;
}
Private function onMouseUpHandler (evt: MouseEvent): void {
TempMc. removeEventListener (Event. ENTER_FRAME, onEnterFrameHandler );
Photo. graphics. clear ();
Render ();
}
Private function onEnterFrameHandler (evt: Event): void {
Var xWidth = mouseX-dx;
Var yWidth = mouseY-dy;
If (xWidth! = 0 | yWidth! = 0 ){
Photo. graphics. clear ();
AngU = angU-xWidth * 0.001;
AngV = angV-yWidth * 0.001;
Cos_angU = Math. cos (angU );
Sin_angU = Math. sin (angU );
Cos_angV = Math. cos (angV );
Sin_angV = Math. sin (angV );
Render ();
}
}
// Initial location of each bitmap subdivision node in the normalized 3D visible space
Private function fun6 (bitmapNo, new19, new20, new21, new22, new25, new23, new26, new24, new27 ){
Var new15 = subdiv-1> 1;
For (var I = 0; I <subdiv; I ++ ){
For (var j = 0; j <subdiv; j ++ ){
Var subID = j + I * subdiv;
SubdivVy [bitmapNo] [subID] = new19 * new15 + new22 * (j-new15) + new25 * (i-new15 );
SubdivVx [bitmapNo] [subID] = new20 * new15 + new23 * (j-new15) + new26 * (i-new15 );
SubdivVz [bitmapNo] [subID] = new21 * new15 + new24 * (j-new15) + new27 * (i-new15 );
// Trace (subdivVy [bitmapNo] [subID] + "/" + subdivVx [bitmapNo] [subID] + "/" + subdivVz [bitmapNo] [subID]);
}
}
}
Private function render (){
For (var I = 0; I <6; I ++ ){
Fun7 (I );
For (var j = 0; j <subdivV; ++ j ){
For (var k = 0; k <subdivV; k ++ ){
Var pointA = k + j * subdiv;
Var pointC = k + (j + 1) * subdiv;
Var pointB = pointA + 1;
Var pointD = pointC + 1;
Var _ loc2 = subdivEnable [I] [pointA] + subdivEnable [I] [pointD] + subdivEnable [I] [pointB];
Var _ loc3 = subdivEnable [I] [pointA] + subdivEnable [I] [pointD] + subdivEnable [I] [pointC];
// If one of the subdivision surface vertices is displayed on the screen, the surface is rendered.
If (_ loc2> 0 ){
// Calculate the stretching range of the subdivided surface
SubBitmapMtix. a = mtrxA;
SubBitmapMtix. B = mtrxB;
SubBitmapMtix. c = mtrxC;
SubBitmapMtix. d = mtrxD;
SubBitmapMtix. tx = mtrx [pointA]. tx;
SubBitmapMtix. ty = mtrx [pointA]. ty;
RenderBitmap (I, subdivX [I] [pointA], subdivY [I] [pointA], subdivX [I] [pointB], subdivY [I] [pointB], subdivX [I] [pointD], subdivY [I] [pointD], subBitmapMtix );
}
// If one of the subdivision surface vertices is displayed on the screen, the surface is rendered.
If (_ loc3> 0 ){
// Calculate the stretching range of the subdivided surface
SubBitmapMtix. a = mtrx2A;
SubBitmapMtix. B = mtrx2B;
SubBitmapMtix. c = mtrx2C;
SubBitmapMtix. d = mtrx2D;
SubBitmapMtix. tx = mtrx2 [pointA]. tx;
SubBitmapMtix. ty = mtrx2 [pointA]. ty;
RenderBitmap (I, subdivX [I] [pointA], subdivY [I] [pointA], subdivX [I] [pointD], subdivY [I] [pointD], subdivX [I] [pointC], subdivY [I] [pointC], subBitmapMtix );
}
}
}
}
}
Private function fun7 (bitmapNo ){
For (var I = 0; I <subdivPic; I ++ ){
// This is the core part: Coordinate System Transformation Calculation of subdivision texture vertices in the camera coordinate space _ loc5 is the z value, and the two equations of _ loc5 and _ loc6 are the simplification of space vector range calculation.
Var _ loc6 = cos_angU * subdivVy [bitmapNo] [I] + sin_angU * subdivVx [bitmapNo] [I];
Var _ loc5 = cos_angV * _ loc6 + sin_angV * subdivVz [bitmapNo] [I];
// If the vertex is in front of the angle of view, the projection calculation is performed.
If (_ loc5> = 0.1 ){
Var _ loc7 = focus/_ loc5;
// Calculate the x, y of the projection.
SubdivX [bitmapNo] [I] = (sin_angU * subdivVy [bitmapNo] [I]-cos_angU * subdivVx [bitmapNo] [I]) * _ loc7 + ox;
SubdivY [bitmapNo] [I] = (sin_angV * _ loc6-cos_angV * subdivVz [bitmapNo] [I]) * _ loc7 + oy;
If (subdivX [bitmapNo] [I]> 0 & subdivX [bitmapNo] [I] <StWidth & subdivY [bitmapNo] [I]> 0 & subdivY [bitmapNo] [i] <StHeight) {
SubdivEnable [bitmapNo] [I] = 1;
} Else {
SubdivEnable [bitmapNo] [I] = 0;
}
}
}
}
Private function renderBitmap (bitmapNo, point1X, point1Y, point2X, point2Y, point3X, point3Y, subBitmapMtix ){
// Subdivision surface texture array calculation
This. bitmapMtrx. a = (point2X-point1X) * inBitmapWidth;
This. bitmapMtrx. B = (point2Y-point1Y) * inBitmapWidth;
This. bitmapMtrx. c = (point3X-point1X) * inBitmapHeight;
This. bitmapMtrx. d = (point3Y-point1Y) * inBitmapHeight;
This. bitmapMtrx. tx = point1X;
This. bitmapMtrx. ty = point1Y;
SubBitmapMtix. concat (this. bitmapMtrx );
// Texture rendering
This. photo. graphics. beginBitmapFill (bitmapSource, subBitmapMtix, false, false );
If (showLine = true ){
This. photo. graphics. lineStyle (000000,100 x );
}
This. photo. graphics. moveTo (point1X, point1Y );
This. photo. graphics. lineTo (point2X, point2Y );
This. photo. graphics. lineTo (point3X, point3Y );
This. photo. graphics. endFill ();
}
Private function drawRec (_ con: Sprite, _ w, _ h, color, num): Sprite {
_ Con. graphics. beginFill (color, num );
_ Con. graphics. drawRect (0, 0, _ w, _ h );
_ Con. graphics. endFill ();
Return _ con;
}
}
}