スポンサーサイト

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

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

[ActionScript 3.0] ベジエ曲面

2007-12-05 | 21:00

黄色の線はベジエ曲面の定義ネット。

package {
        import flash.display.*;
        import flash.events.*;
        import flash.geom.*;
        import flash.utils.*;
        
        import org.papervision3d.core.*;
        import org.papervision3d.core.geom.*;
        import org.papervision3d.scenes.*;
        import org.papervision3d.objects.*;
        import org.papervision3d.cameras.*;
        
        [SWF(width="600", height="400", backgroundColor="#0")]
        public class Bezier extends Sprite{
                
                private var canvas : Sprite;
                private var scene     : MovieScene3D;
                private var camera    : Camera3D;
                
                private var linesU:Array= new Array();
                private var linesV:Array= new Array();
                private var linesUN:Array= new Array();
                private var linesVN:Array= new Array();
                
                private var range:int = 50;
                
                private var WIDTH:int = 600;
                private var HEIGHT:int = 400;
                
                public function Bezier():void
                {
                        stage.frameRate = 20;
                        stage.quality   = "MEDIUM";
                        stage.scaleMode = "noScale";
                        stage.align = StageAlign.TOP_LEFT;
                        
                        canvas = new Sprite();
                        canvas.x = WIDTH/2;
                        canvas.y = HEIGHT/3*2;
                        stage.addChild( canvas );
                        
                        scene = new MovieScene3D( canvas );
                        
                        var x:int,y:int,z:int;
                        
                        scene.addChild( new Line3D([ new Vertex3D(-range*5,0,0), new Vertex3D(range*5,0,0)],
                                                                                              0xff0000, 0.5, 0.2));
                        scene.addChild( new Line3D([ new Vertex3D(0,-range*5,0), new Vertex3D(0,range*5,0)],
                                                                                              0xff00, 0.5, 0.2));
                        scene.addChild( new Line3D([ new Vertex3D(0,0,-range*5), new Vertex3D(0,0,range*5)],
                                                                                              0xff, 0.5, 0.2));
                        
                        
                        camera = new Camera3D();
                        camera.x = 100;
                        camera.y = 100;
                        camera.z = -400;
                        camera.focus = 100;
                        camera.zoom = 60;
                        
                        scene.renderCamera( camera );
                        
                        
                        render();
                        
                        
                        stage.addEventListener(MouseEvent.CLICK, function(e:*):void{
                        });
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, function(e:*):void{
                                var rad:Number = (WIDTH/2- stage.mouseX)/WIDTH*(Math.PI)*2;
                                camera.x = Math.cos(rad)*100 - Math.sin(rad)*(-HEIGHT);
                                camera.z = Math.sin(rad)*100 + Math.cos(rad)*(-HEIGHT);
                                
                                camera.y = (stage.mouseY - HEIGHT/2);
                                
                                scene.renderCamera( camera );
                        });
                }
                
                private function rotateCamera(rad:Number):void{
                        var x:Number = camera.x;
                        var y:Number = camera.y;
                        var z:Number = camera.z;
                        camera.x = Math.cos(rad)*x - Math.sin(rad)*z;
                        //camera.y = Math.cos(rad)*x - Math.sin (rad)*z;
                        camera.z = Math.sin (rad)*x + Math.cos(rad)*z;
                }
                
                private function render():void
                {
                        var m:Model = new Model(range);
                        m.calc();
                        for(var i:int = 0 ; i < linesU.length ; i++)
                        scene.removeChild(linesU[i]);
                        for(i = 0 ; i < linesV.length ; i++)
                        scene.removeChild(linesV[i]);
                        for(i= 0 ; i < linesUN.length ; i++)
                        scene.removeChild(linesUN[i]);
                        for(i= 0 ; i < linesVN.length ; i++)
                        scene.removeChild(linesVN[i]);
                        
                        linesU = linesV = [];
                        linesUN = linesVN = [];
                        
                        for(var u:int = 0 ; u < range+1 ; u++){
                                var vertexes:Array = [];
                                for(var v:int = 0 ; v < range+1 ; v++){
                                        vertexes.push(new Vertex3D(m.buffer[u][v].x, m.buffer[u][v].y, m.buffer[u][v].z));
                                }
                                var line:Line3D = new Line3D(vertexes, 0xffffff, 0.3, 0.05);
                                linesV.push(line);
                                scene.addChild(line);
                        }
                        for(v = 0 ; v < range+1 ; v++){
                                vertexes= [];
                                for(u = 0 ; u < range+1 ; u++){
                                        vertexes.push(new Vertex3D(m.buffer[u][v].x, m.buffer[u][v].y, m.buffer[u][v].z));
                                }
                                line = new Line3D(vertexes, 0xffffff, 0.3, 0.05);
                                linesU.push(line);
                                scene.addChild(line);
                        }
                        
                        for(u = 0 ; u < 4 ; u++){
                                vertexes= [];
                                for(v = 0 ; v < 4 ; v++){
                                        vertexes.push(new Vertex3D(m.net[u][v].x, m.net[u][v].y, m.net[u][v].z));
                                }
                                line = new Line3D(vertexes, 0xffff00, 0.3, 0.1);
                                linesUN.push(line);
                                scene.addChild(line);
                        }
                        for(v = 0 ; v < 4 ; v++){
                                vertexes= [];
                                for(u = 0 ; u < 4 ; u++){
                                        vertexes.push(new Vertex3D(m.net[u][v].x, m.net[u][v].y, m.net[u][v].z));
                                }
                                line = new Line3D(vertexes, 0xffff00, 0.3, 0.1);
                                linesVN.push(line);
                                scene.addChild(line);
                        }
                        
                        scene.renderCamera(camera);
                }
                
        }
}

import org.papervision3d.core.*;
internal class Model{
        public var buffer:Array = new Array();
        
        private var range:int ;
        public var net:Array;
        
        public function Model(range:int){
                this.range = range;
                clear();
        }
        
        public function clear():void{
                buffer = [];
                for(var j:int = 0 ; j < range+1; j++){
                        var aa:Array = new Array();
                        for(var k:int = 0 ; k < range+1; k++)
                        aa.push(new Object());
                        buffer.push(aa);
                }
                
                net = [
                [new Number3D(-20,-10,-20),
                                          new Number3D(-20,10,-5),
                                                       new Number3D(-20,10,5),
                                                                    new Number3D(-20,0,20)],
                                                                                 [new Number3D(-5,5,-20),
                                                                                               new Number3D(-5,15,-5),
                                                                                                            new Number3D(-5,15,5),
                                                                                                                         new Number3D(-5,25,20)],
                                                                                                                                      [new Number3D(5,25,-20),
                                                                                                                                                    new Number3D(5,15,-5),
                                                                                                                                                                 new Number3D(5,5,5),
                                                                                                                                                                              new Number3D(5,15,20)],
                                                                                                                                                                                           [new Number3D(20,10,-20),
                                                                                                                                                                                                         new Number3D(20,10,-5),
                                                                                                                                                                                                                      new Number3D(20,10,5),
                                                                                                                                                                                                                                   new Number3D(20,20,20)]
                ];
        }
        
        public function calc():void{
                for (var u:int = 0 ; u < range+1 ; u++){
                        for (var v:int = 0 ; v < range+1 ; v++){
                                buffer[u][v] = bezier(3, u, v);
                        }
                }
        }
        
        private function bezier(n:int, u:int, v:int):Object{
                
                var result:Number3D = new Number3D();
                
                result.x = net[0][0].x + (net[3][0].x - net[0][0].x)*u/range;
                result.z = net[0][0].z + (net[0][3].z - net[0][0].z)*v/range;
                for (var i:int = 0 ; i <= n ; i++){
                        for (var j:int = 0 ; j <= n ; j++){
                                var ib:Number  = brend(n, i, u/range);
                                var jb:Number  = brend(n, j, v/range);
                                result.y += net[i][j].y*ib*jb;
                        }
                }
                
                return result;
        }
        
        private function brend(n:int, i:int, t:Number):Number
        {
                var ni:Number;
                
                ni = pi(i) * pi(n-i);
                ni = pi(n) / ni;
                
                return ni * Math.pow(t,i) * Math.pow(1-t,n-i);
        }
        
        private function pi(n:int):Number
        {
                if(n == 0)
                return 1;  // 0! = 1 とみなす
                var k:int = 1;
                for (var i:int = n;  i > 1 ; i--)
                k *= i;
                
                return k;
        }
}
スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。