In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Particles 3D

PRESS "R" + CLICK TO ROTATE.
DRAG THE GREEN HANDLERS
// forked from Siroko's Particles 3D
package {

// PRESS "R" + CLICK TO ROTATE.
// DRAG THE GREEN HANDLERS

        import net.hires.debug.Stats;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix3D;
    import flash.geom.Rectangle;
    import flash.geom.Vector3D;
    public class DeformableBezier extends Sprite {

        //Variables que definen la malla...
        private var initLink : Particula = new Particula();
        private var nodos : Array = new Array();
        private var segmentsU : uint;
        private var segmentsV : uint;
        private var cantidad : Number;

        //Puntos de borde...
        private var Xt0 : Vector3D = new Vector3D();
        private var Xt1 : Vector3D = new Vector3D();
        private var Xb0 : Vector3D = new Vector3D();
        private var Xb1 : Vector3D = new Vector3D();

        //Puntos de control internos de las bezier...
        private var Cpt : Vector3D = new Vector3D();
        private var Cpb : Vector3D = new Vector3D();
        private var Cpl : Vector3D = new Vector3D();
        private var Cpr : Vector3D = new Vector3D();

        //Variable que contiene una referencia de los vectores de creación...
        private var pointsReference : Vector.<Vector3D> = new Vector.<Vector3D>;

        //Puntos que controlan el movimiento de los nodos de las curvas... 
        public var angle : Number = 0;

        //BitmapData de representación de las partículas...
        private var bmd : BitmapData;
        private var rect : Rectangle;

        //Variable que controla la rotación del objeto espacialmente....
        private var rotationMatrix : Matrix3D = new Matrix3D();
        private var rotationParentMatrix : Matrix3D = new Matrix3D();
        private const X_AXIS : Vector3D = new Vector3D(1, 0, 0);
        private const Y_AXIS : Vector3D = new Vector3D(0, 1, 0);
        private var PIVOT_POINT : Vector3D = new Vector3D(0, 0, 0);

        //Variable de colorTransform para limpiar el bitmapData...
        private var colorTransform : ColorTransform = new ColorTransform(0, 0, 0, 1, 0, 0, 0);

        //Variable que se encarga de la rotación...
        private var rotate : Boolean;
        private var mouse : Boolean;

        //Varible que contiene los distintas asas de control...
        private var asasContainer : Sprite = new Sprite();
        private var lineContainer : Sprite = new Sprite();
        private var persp : Number;

        //Variable que guarda referencia de las distintas asas de control...
        private var asas : Array = new Array();
        private var pointer : Vector3D;
        private var asasMatrix : Matrix3D;
        private var asasParentMatrix : Matrix3D;

        //Variable que guarda una referencia a la perspectiva utilizada en las transformaciones...
        private var focus : Number = 900;
        private var zoom : Number = 3;
                   
                // Variable de inicialización de la rotacion
                private var init : Boolean = false;
                   
        //Constructor...
        public function DeformableBezier() {
            
            var particle : Particula = initLink;
            Particula.focus = focus;
            Particula.zoom = zoom;
            ControlPoint.focus = focus;
            ControlPoint.zoom = zoom;
            var i : uint;
            var lado : Number = 50;
            
            //Defino los puntos de borde...
            Xt0 = new Vector3D(-lado, 0, -lado);
            Xt1 = new Vector3D(lado, 0, -lado);
            
            Xb0 = new Vector3D(-lado, 0, lado);
            Xb1 = new Vector3D(lado, 0, lado);
            
            //Defino los puntos internos de control...
            Cpt = new Vector3D(0, 0, -lado);
            Cpb = new Vector3D(0, 0, lado);
            Cpl = new Vector3D(-lado, 0, 0);
            Cpr = new Vector3D(lado, 0, 0);
            
            //Guardo los vectores en un vector de referencia...
            pointsReference[0] = Xt0;
            pointsReference[1] = Cpt;
            pointsReference[2] = Xt1;
            pointsReference[3] = Cpr;
            pointsReference[4] = Xb1;
            pointsReference[5] = Cpb;
            pointsReference[6] = Xb0;
            pointsReference[7] = Cpl;
            
            //Inserto las distintas asas en el contenedor...
            for (i = 0;i < 8; i++) {
                asas.push(new ControlPoint(i));
                asas[i].addEventListener(ControlPointEvent.CHANGE, updateControlPoints);
                asasContainer.addChild(asas[i]);
            }
            
            asasContainer.x = stage.stageWidth / 2;
            asasContainer.y = stage.stageHeight / 2;
            
            lineContainer.x = stage.stageWidth / 2;
            lineContainer.y = stage.stageHeight / 2;
            
            //Cantidad de puntos a mostrar...
            segmentsV = 60;
            segmentsU = 60;
            
            //Genero los puntos de las partículas...
            var length : uint = segmentsV * segmentsU;
            for(i = 0;i < length; i++) {
                nodos.push(new Vector3D(0, 0, 0));
            }
                        
            cantidad = nodos.length - 1;
            i = 0;
            while(cantidad >= 0) {
                particle.position = nodos[i];
                particle.next = new Particula();
                particle = particle.next;
                cantidad--;
                i++;
            }
            
            bmd = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0);
            rect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);

            addChild(new Bitmap(bmd, "auto", false));
            addChild(lineContainer);
            addChild(asasContainer);
            addChild(new Stats());
            
            //Inicio la animación...
            stage.addEventListener(KeyboardEvent.KEY_DOWN, initRotation);
            stage.addEventListener(KeyboardEvent.KEY_UP, stopRotation);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
            stage.addEventListener(MouseEvent.MOUSE_WHEEL, updateZoom);
            stage.addEventListener(Event.ENTER_FRAME, updatePoints);
        }

        //Función que se encarga de actualizar los puntos de control...
        private function updateControlPoints(e : ControlPointEvent) : void {
            switch(e.cp) {
                case 0:
                    pointsReference[0] = Xt0 = e.vector;
                    break;
                case 1:
                    pointsReference[1] = Cpt = e.vector;
                    break;
                case 2:
                    pointsReference[2] = Xt1 = e.vector;
                    break;
                case 3:
                    pointsReference[3] = Cpr = e.vector;
                    break;
                case 4:
                    pointsReference[4] = Xb1 = e.vector;
                    break;
                case 5:
                    pointsReference[5] = Cpb = e.vector;
                    break;
                case 6:
                    pointsReference[6] = Xb0 = e.vector;
                    break;
                case 7:
                    pointsReference[7] = Cpl = e.vector;
                    break;
            }
            lineContainer.graphics.clear();
            lineContainer.graphics.lineStyle(0, 0XFFFF00, 1);
            for(var i : uint = 0;i < pointsReference.length; i++) {
                if(i == 0) {
                    lineContainer.graphics.moveTo(asas[i].x, asas[i].y);
                } else {
                    lineContainer.graphics.lineTo(asas[i].x, asas[i].y);
                }                    
            }
            lineContainer.graphics.lineTo(asas[0].x, asas[0].y);
        }

        //Función que ejecuta la animación de manera secuencial...
        private function updatePoints(e : Event) : void {            
            var particle : Particula = initLink;
            var i : uint = 0;
            
            //Defino las curvas bezier...
            //Top...
            var BT : Array = new Array(Xt0, Cpt, Xt1);
            
            //Bottom...
            var BB : Array = new Array(Xb0, Cpb, Xb1);

            //Izquierda...
            var BL : Array = new Array(Xt0, Cpl, Xb0);
            
            //Derecha...
            var BR : Array = new Array(Xt1, Cpr, Xb1);
            
            //Calculo los puntos...    
            nodos = Bezier.getPatch(Xt0, Xt1, Xb0, Xb1, BT, BB, BL, BR, segmentsU, segmentsV);
                        
                        if(!init){
                            init = true;
                            
                            rotationMatrix.identity();
                rotationParentMatrix.identity();
                rotationMatrix.appendRotation(30, Y_AXIS, PIVOT_POINT);
                rotationParentMatrix.appendRotation(30, X_AXIS, PIVOT_POINT);
                
                asasMatrix = rotationMatrix.clone();
                asasParentMatrix = rotationParentMatrix.clone();
                
                lineContainer.graphics.clear();
                lineContainer.graphics.lineStyle(0, 0XFFFF00, 1);
                asasMatrix.invert();
                asasParentMatrix.invert(); 
                
                for(i = 0;i < pointsReference.length; i++) {
                    
                    pointer = pointsReference[i];
                    pointer = rotationMatrix.deltaTransformVector(pointer);
                    pointer = rotationParentMatrix.deltaTransformVector(pointer);
                    persp = zoom / (1 + pointer.z / focus);
                    
                    asas[i].persp = persp;
                    asas[i].matrix = asasMatrix;
                    asas[i].parentMatrix = asasParentMatrix;
                    
                    if(persp > 0) {
                        asas[i].x = pointer.x * persp;
                        asas[i].y = pointer.y * persp;
                        if(i == 0) {
                            lineContainer.graphics.moveTo(asas[i].x, asas[i].y);
                        } else {
                            lineContainer.graphics.lineTo(asas[i].x, asas[i].y);
                        }
                    } else {
                        asas[i].x = asas[i].y = -10000000;
                    }
                }
                lineContainer.graphics.lineTo(asas[0].x, asas[0].y);
                            }
            //Actualizo los asas de control...
            if(rotate && mouse) {
                
                rotationMatrix.identity();
                rotationParentMatrix.identity();
                rotationMatrix.appendRotation(360 * stage.mouseX / stage.stageWidth, Y_AXIS, PIVOT_POINT);
                rotationParentMatrix.appendRotation(90 * stage.mouseY / stage.stageHeight, X_AXIS, PIVOT_POINT);
                
                asasMatrix = rotationMatrix.clone();
                asasParentMatrix = rotationParentMatrix.clone();
                
                lineContainer.graphics.clear();
                lineContainer.graphics.lineStyle(0, 0XFFFF00, 1);
                asasMatrix.invert();
                asasParentMatrix.invert(); 
                
                for(i = 0;i < pointsReference.length; i++) {
                    
                    pointer = pointsReference[i];
                    pointer = rotationMatrix.deltaTransformVector(pointer);
                    pointer = rotationParentMatrix.deltaTransformVector(pointer);
                    persp = zoom / (1 + pointer.z / focus);
                    
                    asas[i].persp = persp;
                    asas[i].matrix = asasMatrix;
                    asas[i].parentMatrix = asasParentMatrix;
                    
                    if(persp > 0) {
                        asas[i].x = pointer.x * persp;
                        asas[i].y = pointer.y * persp;
                        if(i == 0) {
                            lineContainer.graphics.moveTo(asas[i].x, asas[i].y);
                        } else {
                            lineContainer.graphics.lineTo(asas[i].x, asas[i].y);
                        }
                    } else {
                        asas[i].x = asas[i].y = -10000000;
                    }
                }
                lineContainer.graphics.lineTo(asas[0].x, asas[0].y);
            }
            
            i = 0;
            bmd.lock();
            bmd.colorTransform(bmd.rect, colorTransform);
            
            //Actualizo las posiciones de las partículas...
            while(particle.next != null) {
                
                pointer = nodos[i];
                pointer = rotationMatrix.deltaTransformVector(pointer);
                pointer = rotationParentMatrix.deltaTransformVector(pointer);
                particle.position = pointer;

                bmd.setPixel(Math.round(stage.stageWidth / 2 + particle.x), Math.round(stage.stageHeight / 2 + particle.y), 0XFFFFFF);
                particle = particle.next;
                i++;
            }
            
            bmd.unlock();
        }

        //Función que se encarga de iniciar la rotación...
        private function initRotation(e : KeyboardEvent) : void {
            if(e.charCode == 114) rotate = true;
        }

        //Función que para la rotación...
        private function stopRotation(e : KeyboardEvent) : void {
            if(e.charCode == 114) rotate = false;
        }

        //Función que señala que el ratón esta presionado...
        private function mouseDownListener(E : MouseEvent) : void {
            mouse = true;
        }

        //Función que señala que el ratón esta presionado...
        private function mouseUpListener(E : MouseEvent) : void {
            mouse = false;
        }

        //Función que se encarga de modificar el zoom...
        private function updateZoom(e : MouseEvent) : void {
            trace(e.delta);
            zoom += e.delta / 10;
            Particula.zoom = zoom;
            ControlPoint.zoom = zoom;
            var persp : Number;
            lineContainer.graphics.clear();
            lineContainer.graphics.lineStyle(0, 0XFFFF00, 1);
            for(var i : uint = 0;i < pointsReference.length; i++) {
                var pointer : Vector3D = pointsReference[i];
                pointer = rotationMatrix.deltaTransformVector(pointer);
                pointer = rotationParentMatrix.deltaTransformVector(pointer);
                persp = zoom / (1 + pointer.z / focus);
                asas[i].persp = persp;
                var asasMatrix : Matrix3D = rotationMatrix.clone();
                asasMatrix.invert();
                var asasParentMatrix : Matrix3D = rotationParentMatrix.clone();
                asasParentMatrix.invert(); 
                asas[i].matrix = asasMatrix;
                asas[i].parentMatrix = asasParentMatrix;
                if(persp > 0) {
                    asas[i].x = pointer.x * persp;
                    asas[i].y = pointer.y * persp;
                    if(i == 0) {
                        lineContainer.graphics.moveTo(asas[i].x, asas[i].y);
                    } else {
                        lineContainer.graphics.lineTo(asas[i].x, asas[i].y);
                    }
                } else {
                    asas[i].x = asas[i].y = -10000000;
                }
            }
            lineContainer.graphics.lineTo(asas[0].x, asas[0].y);
        }
    }
}

class MathFunctions {

    //Función que se encarga de generar un signo aleatorio...
    public static function signo() : Number {
        return Math.random() >= 0.5 ? 1 : -1;
    }
    //Función que cambia de degrees a radianes...
    public static function radians(angle : Number) : Number {
        return angle * Math.PI / 180;
    }
    //Función que cambia de radianes  adegrees...
    public static function degrees(angle : Number) : Number {
        return angle * 180 / Math.PI;
    }

    //Función que se encarga de la combinatoria entre dos números...
    public static function combinatoria(n : Number, i : Number) : Number {
        return factorial(n) / (factorial(i) * factorial(n - i));
    }

    //Función que calcula el factorial de un número entero
    public static function factorial(n : Number) : Number {
            
        var i : Number;
        var salida : Number = 1;
        if(n != 0) {
            for(i = 1;i <= n; i++) {
                salida *= i;
            }
        } else {
            salida = 1;
        }
        
        return salida;
    }
    
    
    //Fin del programa....
}

import flash.geom.Vector3D;            

/**
 * @author hector arellano
 * Clase que se encarga de generar una parametrización
 * Bezier de trayectoria o superficie.
 * 
 */
class Bezier {
    //Variable que permite tener los datos de la combinatoria para cada grado...
    private static var combinatoriaData : Array = new Array();
    combinatoriaData[0] = [0];
    combinatoriaData[1] = [1];
    
    //A partír de 2 se tienen la cantidad mínima de puntos para interpolar
    combinatoriaData[2] = new Array(1, 1);
    combinatoriaData[3] = new Array(1, 2, 1);
    combinatoriaData[4] = new Array(1, 3, 3, 1);
    combinatoriaData[5] = new Array(1, 4, 6, 4, 1);
    combinatoriaData[6] = new Array(1, 5, 10, 10, 5, 1);
    combinatoriaData[7] = new Array(1, 6, 15, 20, 15, 6, 1);
    combinatoriaData[8] = new Array(1, 7, 21, 35, 35, 21, 7, 1);
    combinatoriaData[9] = new Array(1, 8, 28, 56, 70, 56, 28, 8, 1);
    combinatoriaData[10] = new Array(1, 9, 36, 84, 126, 126, 84, 36, 9, 1);
    combinatoriaData[11] = new Array(1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1);
    combinatoriaData[12] = new Array(1, 11, 56, 165, 330, 462, 462, 330, 165, 56, 11, 1);

    //Variables estáticas que permiten guardar los valores de segmentación de la malla (evita recalcular la cantidad de puntos...)
    private static var Ne : uint = 0;
    private static var Nn : uint = 0;
    private static var paramsE : Array = new Array();
    private static var paramsN : Array = new Array();

    //Variable que contiene las constantes de la curva bezier para un grado y una parametrización (cantidad de puntos) fija.
    private static var coeficientesCurva : Array = new Array(); 
    //Función que calcula los coeficientes de la curva...
    public static function bezier(t : Number, controlPoints : Array) : Vector3D {
            
        var salida : Vector3D = new Vector3D;
        var coeficientes : Array = new Array();
        var i : uint;
        var n : uint = controlPoints.length - 1;
            
        //Si los valores de la combinatoria para la cantidad de puntos no estan definidos, los defino...
        if(combinatoriaData[controlPoints.length] == undefined) {
            combinatoriaData[controlPoints.length] = setCoeficients(n);
        }
        
        //Determino los coeficientes...
        for (i = 0;i <= n; i++) {
            coeficientes[i] = combinatoriaData[controlPoints.length][i] * Math.pow(t, i) * Math.pow((1 - t), (n - i));
        }
        
        //Obtengo los valores de salida del vector3D...
        for(i = 0;i <= n; i++) {
            salida.x += coeficientes[i] * controlPoints[i].x;
            salida.y += coeficientes[i] * controlPoints[i].y;
            salida.z += coeficientes[i] * controlPoints[i].z;
        }
        salida.w = 1;
        
        return salida;
    }

    //Función que se encarga de obtener un conjunto de puntos xyz agrupados en un array para una curva bezier...
    public static function bezierPoints(m : uint, controlPoints : Array) : Vector.<Vector3D> {
        var salida : Vector.<Vector3D> = new Vector.<Vector3D>();
        var n : uint = controlPoints.length - 1;
        var i : uint;
        var j : uint;
        
        //Si los valores de la combinatoria para la cantidad de puntos no estan definidos, los defino...
        if(combinatoriaData[controlPoints.length] == undefined) {
            combinatoriaData[controlPoints.length] = setCoeficients(m);
        }
        
        //Si no hay un arreglo que guarde la referencia para un grado definido, se define...
        if(coeficientesCurva[n] == undefined) {
            coeficientesCurva[n] = new Array();
        }
        
        //Si no hay un arreglo que guarde los coeficientes para "m" puntos se define...
        //Se guarda un arreglo de cuatro dimensiones según la siguiente definición...
        //
        //coeficientes[n][m][j][i] donde:
        //n : grado,
        //m : cantidad de puntos a parametrizar,
        //j : vector de coeficientes para un valor de parametrización perteneciente al rango [0, 1]
        //i : coeficientes a multiplicar por cada punto para la parametrización anterior...
        //
        if(coeficientesCurva[n][m] == undefined) {
            coeficientesCurva[n][m] = new Array();
            for (j = 0;j < m; j++) {
                //Defino la parametrización...
                var delta : Number = j / (m - 1);
                coeficientesCurva[n][m][j] = new Array();
                for(i = 0;i <= n; i++) {
                    coeficientesCurva[n][m][j].push(combinatoriaData[controlPoints.length][i] * Math.pow(delta, i) * Math.pow((1 - delta), (n - i)));
                }
            }
        }
        
        //Obtengo los distintos puntos que componen el vector de salida...
        for(j = 0;j < m; j++) {
            var pointer : Vector3D = new Vector3D();
            for(i = 0;i <= n; i++) {
                pointer.x += coeficientesCurva[n][m][j][i] * controlPoints[i].x;
                pointer.y += coeficientesCurva[n][m][j][i] * controlPoints[i].y;
                pointer.z += coeficientesCurva[n][m][j][i] * controlPoints[i].z;
            }
            pointer.w = 1;
            salida.push(pointer);
        }
        
        return salida;
    }
    //Función que se encarga de conseguir todos los puntos de una malla generada por bordes...
    //Entrega los puntos ordenados de la siguiente manera suponiendo un arreglo de 3X3...
    //
    //  0  1  2
    //  3  4  5
    //  6  7  8
    //
    public static function getPatch(Xt0 : Vector3D, Xt1 : Vector3D, Xb0 : Vector3D, Xb1 : Vector3D, BT : Array, BB : Array, BL : Array, BR : Array, Ne : uint = 10, Nn : uint = 10) : Array {
            
        var i : uint;
        var points : Array = new Array();
        
        //Obtengo los puntos de las curvas para interpolar...
        var b_top : Vector.<Vector3D> = Bezier.bezierPoints(Ne, BT);
        var b_bottom : Vector.<Vector3D> = Bezier.bezierPoints(Ne, BB);
        var b_left : Vector.<Vector3D> = Bezier.bezierPoints(Nn, BL);
        var b_right : Vector.<Vector3D> = Bezier.bezierPoints(Nn, BR);
        
        
        //Genero los parámetros si no estan definidos...
        if(Bezier.Ne != Ne && Bezier.Nn != Ne) {
            Bezier.Ne = Ne;
            Bezier.Nn = Nn;
            paramsN = [];
            paramsE = [];
            for (i = 1;i <= Nn; i++) {
                paramsN.push((i - 1) / (Nn - 1));
            }
        
            for (i = 1;i <= Ne; i++) {
                paramsE.push((i - 1) / (Ne - 1));
            }
        }
        
        //Genero el arreglo de puntos...
        var j : uint;
        var jMax : uint = paramsN.length;
        var iMax : uint = paramsE.length;
        for (j = 0;j < jMax; j++) {
            for (i = 0;i < iMax; i++) {
                points.push(TFI(paramsE[i], paramsN[j], b_top[i], b_bottom[i], b_left[j], b_right[j], Xt0, Xt1, Xb0, Xb1));
            }
        }
        
        return points;
    }
    
    //Función que permite liberar la memoria de la clase Bezier...
    public static function clearMemory() : void{
        coeficientesCurva = [];
        paramsN = [];
        paramsE = [];
        combinatoriaData = [];
        
        coeficientesCurva = paramsN = paramsE = combinatoriaData = null;
    }

    //Función que genera una interpolación tranfinita TFI para un grupo de cuatro curvas de borde bezier.
    //Se pasan los puntos de borde Xt0, Xt1, Xb0, Xb1 y los valores e, n definidos de 0 a 1 para pasar de
    //estado plano al definido por las cuatro curvas... se busca generar los puntos P intermedios...
    //
    // 
    //  Xt0 Xt Xt Xt Xt Xt Xt Xt1
    //  Xl                     Xr
    //  Xl                     Xr
    //  Xl   P                 Xr
    //  Xl                     Xr
    //  Xl                     Xr
    //  Xl                     Xr
    //  Xl                     Xr
    //  Xb0 Xb Xb Xb Xb Xb Xb Xb1
    //
    //
    private static function TFI(e : Number, n : Number, Xt : Vector3D, Xb : Vector3D, Xl : Vector3D, Xr : Vector3D , Xt0 : Vector3D, Xt1 : Vector3D, Xb0 : Vector3D, Xb1 : Vector3D) : Vector3D {
            
        var TFIPoint : Vector3D = new Vector3D();
            
        //Evalúo la interpolación para cada coordenada del punto, x, y, z...
        TFIPoint.x = (1 - n) * Xt.x + n * Xb.x + (1 - e) * Xl.x + e * Xr.x - (e * n * Xb1.x + e * (1 - n) * Xt1.x + n * (1 - e) * Xb0.x + (1 - n) * (1 - e) * Xt0.x);
        TFIPoint.y = (1 - n) * Xt.y + n * Xb.y + (1 - e) * Xl.y + e * Xr.y - (e * n * Xb1.y + e * (1 - n) * Xt1.y + n * (1 - e) * Xb0.y + (1 - n) * (1 - e) * Xt0.y);
        TFIPoint.z = (1 - n) * Xt.z + n * Xb.z + (1 - e) * Xl.z + e * Xr.z - (e * n * Xb1.z + e * (1 - n) * Xt1.z + n * (1 - e) * Xb0.z + (1 - n) * (1 - e) * Xt0.z);
        TFIPoint.w = 1;
        return TFIPoint;
    }

    //Función que realiza un set de los coeficientes en caso que cantidad de puntos sean distintos a los valores almacenados...
    private static function setCoeficients(n : Number) : Array {
        var datos : Array = new Array();
        var i : Number;
        for (i = 0;i <= n; i++) {
            datos.push(MathFunctions.combinatoria(n, i));
        }
        return datos;
    }
        
        
    //fín del programa....
}

import flash.geom.Point;
import flash.geom.Vector3D;
class Particula {

    public var next : Particula = null;
    public var x : Number;
    public var y : Number;
    public static var focus : Number = 300;
    public static var zoom : Number = 0;

    private var persp : Number;

    public function Particula() {
        //En la posición w del vector se define la modificación por la música....
    }
    public function set position(vector : Vector3D) : void {
        persp = zoom * focus / (focus + vector.z);
        if(persp > 0) {
            this.x = vector.x * persp;
            this.y = vector.y * persp;
        } else {
            this.x = this.y = -10000000;
        }
    }
    public function get XY() : Point {
        return new Point(this.x, this.y);
    }
        
    //Fín del programa...
}

import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;    
class ControlPoint extends Sprite {

    public var persp : Number;
    public var matrix : Matrix3D;
    public var parentMatrix : Matrix3D;

    //Variable que guarda la referencia al punto ...
    private var id : uint;
    private var lado : uint = 7;
    //Variable que guarda una referencia a la perspectiva utilizada en las transformaciones...
    public static var focus : Number = 0;
    public static var zoom : Number = 0;

    public function ControlPoint(id : uint) {
        this.id = id;
        graphics.lineStyle(0, 0X00FF00, 1);
        graphics.beginFill(0);
        graphics.drawRect(-lado / 2, -lado / 2, lado, lado);
        this.buttonMode = true;
        
        this.addEventListener(MouseEvent.MOUSE_DOWN, update3DPosition);
    }
    //Función que se encarga de actualizar la posición 3D del asa de tangencia en base a su posición 2D...
    private function update3DPosition(e : MouseEvent) : void {
        this.startDrag();
        trace(id);
        this.addEventListener(Event.ENTER_FRAME, updatePosition);
        stage.addEventListener(MouseEvent.MOUSE_UP, stopDragEvent);
    }
        
        
    //Función que se encarga de actualizar la posición...
    private function updatePosition(e : Event) : void {
        
        var salida : Vector3D = new Vector3D();
        salida.x = this.x / persp;
        salida.y = this.y / persp;
        salida.z = focus * (zoom - persp) / persp;
        
        salida = parentMatrix.deltaTransformVector(salida);
        salida = matrix.deltaTransformVector(salida);
        dispatchEvent(new ControlPointEvent(ControlPointEvent.CHANGE, salida, id));
        
    }
    
    //Función que se encarga de parar el arrastre...
    private function stopDragEvent(e : MouseEvent) : void {
        this.stopDrag();
        this.removeEventListener(Event.ENTER_FRAME, updatePosition);
        stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragEvent);
    }
    //Fín del programa...
}

import flash.events.Event;
import flash.geom.Vector3D;
class ControlPointEvent extends Event {
    
    //Variable estática del tipo de evento..
    public static const CHANGE : String = "CHANGE";
    
    //Puntos del arreglo...
    public var vector : Vector3D;
    public var cp : uint;
    
    //Constructor...
    public function ControlPointEvent(type : String, vector : Vector3D, cp : uint, bubbles : Boolean = false, cancelable : Boolean = false) : void {
        super(type, bubbles, cancelable);
        this.cp = cp;
        this.vector = vector;
    }
    
    //Función que devuelve un clon del evento...
    public override function clone() : Event {
        return new ControlPointEvent(type, vector, cp, bubbles, cancelable);
    }
}