用户名:  密码:
兄弟在线   

标题:Bitmap透视变换PerspectiveTransform

作者:佚名 来源:一聚教程 时间:2011-09-15

Bitmap变换PerspectiveTransform

 

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;
  //鼠标按下时bitmap的变换距阵
  var bitmapMtrx = new Matrix();
  var subBitmapMtix = new Matrix();
  //舞台宽度变量申明
  var StWidth = 550;
  var StHeight = 400;
  var ox;
  var oy;
  //焦距
  var focus = 80;
  //摄影机角度变量
  var angU = 0;
  var angV = 0;
  //细分段数
  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();
  //细分bitmap在map内部的X和Y
  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].a;
   mtrxB = mtrx[0].b;
   mtrxC = mtrx[0].c;
   mtrxD = mtrx[0].d;
   mtrx2A = mtrx2[0].a;
   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,1,0,0,0,0,-1,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();
   }
  }
  // 初始每个bitmap细分结点在正则化3D视见体空间中的空间位置
  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];
      //如果细分表面顶点有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);
      }
     }
    }
   }
  }
  private 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;
     }
    }
   }
  }
  private 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();
  }
  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;
  }
 }
}



编辑:admin 总点击 [932]   评论  0 查看评论
上一篇:BitmapData类的精确碰撞测试
下一篇:图片随鼠标反向缓冲
【关闭窗口】
您可能感兴趣的文章
我要评论
          
评论标题:   可以输入250
 
验证数字: 8 + 4 =
兄弟友情提示
· 请自觉遵守国家有关法律、法规,尊重网上道德。
· 兄弟在线坚决抵制不良言行,违者文责自负。
· 如果文章有版权或其他问题等,请联系我们,我们会尽快处理。
· 文章注名来自网络的旨在传播共享信息,不做其它用途;注名原创的本站支持原创,但不代表同意其观点。
· 兄弟在线拥有管理用户与其文章和评论的一切权利,并有权在网站内转载或引用。
兄弟在线
兄弟热门文章
兄弟推荐文章
兄弟站内搜索

兄弟感兴趣的文章
兄弟最新影视