スポンサーサイト

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

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

回転行列の列ベクトル

2008-01-08 | 22:49

回転行列

| n11 n12 n13 |
| n21 n22 n23 |
| n31 n32 n33 |

の列ベクトル (n11, n21, n31) (n12, n22, n32) (n13, n23, n33) は基準座標系のそれぞれx,y,z軸の単位ベクトルを表している。
つまり回転行列がわかっているなら、基準座標系のx,y,z軸の単位ベクトルがすぐにわかる。
PaperVision3DではDisplayObject3D.transformに姿勢行列が格納されているので、それを参照すればそのオブジェクトの今の姿勢(各軸のベクトル)がわかる。

下のウィンドウをクリックしてフォーカスを移動した後、赤いキューブは Rキーでロー/ Pキーでピッチ / Yキーでヨー の回転を行います。
回転させた後、キューブの姿勢行列から基準座標のX軸Y軸Z軸を求めて赤/青/緑の太線で表示させています。

package {
        import flash.display.*;
        import flash.events.*;
        
        import org.papervision3d.core.*;
        import org.papervision3d.core.math.*;
        import org.papervision3d.core.geom.*;
        import org.papervision3d.scenes.*;
        import org.papervision3d.objects.primitives.*;
        import org.papervision3d.cameras.*;
        import org.papervision3d.materials.*;
        import org.papervision3d.materials.shadematerials.*;
        import org.papervision3d.materials.utils.*;
        import org.papervision3d.view.*;
        import org.papervision3d.render.*;
        import org.papervision3d.lights.*;
        import org.papervision3d.materials.special.LineMaterial;
        
        [SWF(width="400", height="400", backgroundColor="#ffffff")]
        public class MatVec extends Sprite{
                private var renderer:BasicRenderEngine = new BasicRenderEngine();
                private var viewport:Viewport3D = new Viewport3D(400, 400, false, true);
                private var scene:Scene3D = new Scene3D();
                private var camera:Camera3D = new Camera3D();
                private var redCube:Cube;
                
                private var xLines:Lines3D = null;
                private var yLines:Lines3D = null;
                private var zLines:Lines3D = null;
                
                public function MatVec():void
                {
                        stage.align = StageAlign.TOP_LEFT;
                        stage.scaleMode = StageScaleMode.NO_SCALE;
                        
                        addChild(viewport);
                        
                        camera.y = 0;
                        camera.z = -550;
                        camera.x = 0;
                        camera.focus = 1100;
                        camera.zoom = 1;
                        
                        var m:WireframeMaterial = new WireframeMaterial( 0xff0000 );
                        redCube = new Cube(new MaterialsList({all:m}), 100, 100, 100);
                        redCube.x = 100;
                        redCube.y = 100;
                        scene.addChild(redCube);
                        
                        camera.target = redCube;
                        
                        var lines:Lines3D = new Lines3D(new LineMaterial());
                        scene.addChild(lines);
                        lines.addNewLine(1, -300,0,0, 300,0,0);
                        
                        var blueLines:Lines3D = new Lines3D(new LineMaterial(0xff));
                        scene.addChild(blueLines);
                        blueLines.addNewLine(1, 0,-300,0, 0,300,0);
                        
                        var greenLines:Lines3D = new Lines3D(new LineMaterial(0xff00));
                        scene.addChild(greenLines);
                        greenLines.addNewLine(1, 0,0,-300, 0,0,300);
                        
                        stage.addEventListener(KeyboardEvent.KEY_DOWN, function(e:KeyboardEvent):void{
                                rotate(e.keyCode);
                        });
                        
                        showVector();
                }
                
                private function rotate(keyCode:int):void{
                        switch (keyCode){
                                case 80 :// p
                                redCube.pitch(1);
                                break;
                                case 82 :// r
                                redCube.roll(1);
                                break;
                                case 89 :// y
                                redCube.yaw(1);
                                break;
                        }
                        showVector();
                }
                
                private function showVector():void{
                        if(xLines != null){
                                scene.removeChild(xLines);
                                scene.removeChild(yLines);
                                scene.removeChild(zLines);
                        }
                        
                        var m:Matrix3D = redCube.transform;
                        
                        xLines = new Lines3D(new LineMaterial());
                        scene.addChild(xLines);
                        xLines.addNewLine(3, redCube.x,redCube.y,redCube.z,
                                                         redCube.x + m.n11*100, redCube.y + m.n21*100 , redCube.z + m.n31*100);
                        
                        yLines =  new Lines3D(new LineMaterial(0xff));
                        scene.addChild(yLines);
                        yLines.addNewLine(3, redCube.x,redCube.y,redCube.z,
                                                         redCube.x + m.n12*100, redCube.y + m.n22*100 , redCube.z + m.n32*100);
                        
                        zLines = new Lines3D(new LineMaterial(0xff00));
                        scene.addChild(zLines);
                        zLines.addNewLine(3, redCube.x,redCube.y,redCube.z,
                                                         redCube.x + m.n13*100, redCube.y + m.n23*100 , redCube.z + m.n33*100);
                        
                        renderer.renderScene(scene, camera, viewport);
                }
        }
}


スポンサーサイト

Comment

Post a comment

Secret

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