Bitmap透视变换
Bitmap变换
import flash.geom.*;
var photo:Sprite=new Sprite();
addChild(photo);
//Img为继承于BitmapData的图片类
var bitmapSource = new Img(400,300);
var showLine = true;
var inBitmapWidth = 1/bitmapSource.width;
var inBitmapHeight = 1/bitmapSource.height;
var bitmapWidth = bitmapSource.width;
var bitmapHeight = bitmapSource.height;
//鼠标按下时bitmap的变换距阵
var bitmapMtrx = new Matrix();
var subBitmapMtix = new Matrix();
//舞台宽度变量申明
var StWidth = 550;
var StHeight = 400;
var ōx = StWidth/2;
var ōy = StHeight/2;
//焦距
var focus = 80;
//摄影机角度变量
var angU = 0;
var angV = 0;
//细分段数
var subdiv = 5;
var subdivPic = subdiv*(subdiv-1);
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();
//细分bitmap在map内部的X和Y
var subdivMapX = new Array();
var subdivMapY = new Array();
var subdivWidth = bitmapSource.width/(subdiv-1);
var subdivHeight = bitmapSource.height/(subdiv-1);
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));
}
var mtrxSx = subdivWidth/bitmapWidth;
var mtrxSy = subdivHeight/bitmapHeight;
var mtrxSxy = subdivWidth/bitmapHeight;
var mtrxSyx = subdivHeight/bitmapWidth;
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();
}
}
var mtrxA = mtrx[0].a;
var mtrxB = mtrx[0].b;
var mtrxC = mtrx[0].c;
var mtrxD = mtrx[0].d;
var mtrx2A = mtrx2[0].a;
var mtrx2B = mtrx2[0].b;
var mtrx2C = mtrx2[0].c;
var mtrx2D = mtrx2[0].d;
// 初始每个bitmap细分结点在正则化3D视见体空间中的空间位置
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]);
}
}
}
fun6(0,1,0,0,0,0,-1,0,0,-1);
function fun7(bitmapNo) {
for (var i = 0; i<subdivPic; i++) {
//此为核心部分:细分贴图顶点在camera坐标空间中的坐标系变换运算 _loc5为z值,_loc5与_loc6的两个方程是对空间向量距阵计算的简化
var _loc6 = cos_angU*subdivVy[bitmapNo][i]+sin_angU*subdivVx[bitmapNo][i];
var _loc5 = cos_angV*_loc6+sin_angV*subdivVz[bitmapNo][i];
//如果顶点在视角前方则进行投影计算
if (_loc5>=0.1) {
var _loc7 = focus/_loc5;
//计算投影的x,y
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;
}
}
}
}
var subdivV = subdiv-1;
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];
//如果细分表面顶点有1个在屏幕内则渲染该面片
if (_loc2>0) {
//细分表面拉伸距阵计算
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);
}
//如果细分表面顶点有1个在屏幕内则渲染该面片
if (_loc3>0) {
//细分表面拉伸距阵计算
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);
}
}
}
}
}
function renderBitmap(bitmapNo, point1X, point1Y, point2X, point2Y, point3X, point3Y, subBitmapMtix) {
//细分表面贴图距阵计算
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);
//贴图渲染
this.photo.graphics.beginBitmapFill(bitmapSource,subBitmapMtix,false,false);
if (showLine == true) {
this.photo.graphics.lineStyle(1,0x000000,100);
}
this.photo.graphics.moveTo(point1X,point1Y);
this.photo.graphics.lineTo(point2X,point2Y);
this.photo.graphics.lineTo(point3X,point3Y);
this.photo.graphics.endFill();
}//初始渲染
photo.graphics.clear();
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;
stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUpHandler);
function onMouseDownHandler(evt:MouseEvent):void {
stage.addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
dx = mouseX;
dy = mouseY;
}
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();
}
}
function onMouseUpHandler(evt:MouseEvent):void {
stage.removeEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
photo.graphics.clear();
render();
}
render();
补充:flash教程,Action