スポンサーサイト

-------- | --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[ActionScript 3.0] 画像の3D回転

2007-11-08 | 19:57

画像をY軸を中心に回転しているように見せる場合、回転角のコサイン値をscaleXに与えればそれらしく見える。(上の画像)
ただし、奥行き間がないのでどちらの方向に回転しているのかわからない。
奥行き間がでるように変形したのが下の画像。
package {

    import flash.display.*;
    import flash.events.*;

    [SWF(width="500", height="350", backgroundColor="#ffffff")]
        public class Main extends Sprite{
            [Embed(source="lena.jpg")]
                private var Bm:Class;
            private var img:TDImage;
            private var rad:Number=0;

            public function Main()
            {
                var bm1:Bitmap = new Bm();
                addChild(bm1);
                bm1.x = 250;
                var bm2:Bitmap = new Bm();
                img = new TDImage(bm2);
                img.distance = 500;
                img.x = 250;
                img.y = bm1.height + 50;
                addChild(img);

                addEventListener(Event.ENTER_FRAME, function(e:*):void{
                        rad+= 0.01;
                        bm1.scaleX = Math.cos(rad);
                        img.rotateByRadian(rad);
                        });

            }
        }
}

import flash.display.*;
import flash.geom.*;
internal class TDImage extends Sprite{
    public var distance:Number = 600; // 射影面から画像までの距離
    public var e:Number = 10; // 視点から射影面までの距離
    private var bm:Bitmap;
    public function TDImage(bm:Bitmap){
        this.bm = bm;
    }

    public function rotateByRadian(theta:Number):void{
        graphics.clear();
        var scaleW:Number = Math.cos(theta);
        var scaleH:Number = (e+distance)/(e+distance+bm.width*Math.sin(theta));
        // p0       p1
        //      p6
        // p2   p8  p3
        //      p7
        // p4       p5
        var p0:Point = new Point(0,        0);
        var p1:Point = new Point(bm.width, 0);
        var p2:Point = new Point(0,        bm.height/2);
        var p3:Point = new Point(bm.width, bm.height/2);
        var p4:Point = new Point(0,        bm.height);
        var p5:Point = new Point(bm.width, bm.height);

        var p6:Point = new Point(bm.width*scaleW, bm.height*(0.5-scaleH/2));
        var p7:Point = new Point(bm.width*scaleW, bm.height*(0.5+scaleH/2));
        var p8:Point = new Point(bm.width*scaleW, bm.height/2);

        transformTriangle(p0, p1, p2, p0, p6, p2);
        transformTriangle(p2, p1, p3, p2, p6, p8);
        transformTriangle(p2, p3, p5, p2, p8, p7);
        transformTriangle(p2, p5, p4, p2, p7, p4);
    }
    public function transformTriangle(a0:Point, a1:Point, a2:Point, b0:Point, b1:Point, b2:Point):void{
        // [a0-a1,a0-a2]が表す座標系に変換する行列
        var matrixA:Matrix = new Matrix( a1.x - a0.x, a1.y - a0.y, a2.x - a0.x, a2.y - a0.y);

        // [b0-b1,b0-b2]が表す座標系に変換する行列
        var matrixB:Matrix = new Matrix( b1.x - b0.x, b1.y - b0.y, b2.x - b0.x, b2.y - b0.y); 

        // 三角形 a0-a1-a2のa0が原点に移動するように変換する行列
        var m:Matrix = new Matrix(1,0,0,1,-a0.x,-a0.y);

        // [a0-a1,a0-a2]が表す座標系に変換
        matrixA.invert();
        m.concat(matrixA);

        // [b0-b1,b0-b2]が表す座標系に変換
        m.concat(matrixB);

        // 原点からb0へ移動 
        m.translate(b0.x, b0.y);

        // 求めた行列を使ってビットマップを変形
        graphics.beginBitmapFill(bm.bitmapData, m);
        drawTriangle(a0, a1, a2, m);
        graphics.endFill();
    }

    private function drawTriangle(p0:Point, p1:Point, p2:Point, m:Matrix):void{

        p0 = m.transformPoint(p0);
        p1 = m.transformPoint(p1);
        p2 = m.transformPoint(p2);

        graphics.moveTo(p0.x, p0.y);
        graphics.lineTo(p1.x, p1.y);
        graphics.lineTo(p2.x, p2.y);
        graphics.lineTo(p0.x, p0.y);
    }        
}

スポンサーサイト

Comment

Post a comment

Secret

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。