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 = 600;
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);
}
}