En Adobe Flash CS4 se introdujo el método drawTriangles() a la clase Graphics. Este método puede tener diversas aplicaciones pero en este caso escribiré acerca del manejo y creación de figuras tridimensionales a partir de triángulos.
Mueve el cursor sobre el cubo para poder manipularlo.
Antes de meternos en códigos recomendaría que hayan leído y comprendido o en su defecto tener un poco de conocimientos sobre cómo funciona el método drawTriangles(), una vez de acuerdo en ello lo que haremos sera crear un documento y seleccionar el primer fotograma clave que sera donde trabajaremos.
Una vez listos, comenzaremos creando un Sprite cuyo nombre sera "cubo" y lo añadiremos al escenario:
var cubo:Sprite = new Sprite();
addChild(cubo);
Luego tenemos que buscar con que rellenarlo, así es que crearemos los tres vectores que contendrán las coordenadas de los vértices (vector points) y los aristas:
var points:Vector.<Number> = new Vector.<Number>;
var vertices:Vector.<Number> = new Vector.<Number>;
var aristas:Vector.<int> = new Vector.<int>;
Comenzaremos con los vértices, que para hacerlos mas fácil modificar utilizare una contante llamada "largo" con un valor a 50.
var largo:int = 50
//
points = Vector.<Number>([
largo, -largo, largo, // P1
largo, -largo, -largo, // P2
-largo, -largo, -largo, // P3
-largo, -largo, largo, // P4
largo, largo, largo, // P5
largo, largo, -largo, // P6
-largo, largo, -largo, // P7
-largo, largo, largo // P8
]);
Atención, es por esto que hubiese sido bueno que leyeras esto ya que utilizando cada uno de los puntos ya fijos en sus coordenadas que formaran los vértices (vector points) fijaremos cada uno de los triángulos que como sabemos serán 2 por cada cara dando 12 triángulos en total:
aristas = Vector.<int>([
2,5,1, // T1: P2-P5-P1
3,2,1, // T2: P3-P2-P1
5,6,7, // T3: P5-P6-P7
7,3,0, // T4: P7-P3-P0
1,5,4, // T5: P1-P5-P4
2,6,5, // T6: P2-P6-P5
1,4,0, // T7: P1-P4-P0
3,6,2, // T8: P3-P6-P2
3,7,6, // T9: P3-P7-P6
5,7,4, // T10: P5-P7-P4
3,1,0, // T11: P3-P1-P0
7,0,4 // T12: P7-P0-P4
]);
Con esto ya tenemos toda la información necesaria para dibujar los 12 triángulos que conformaran el cubo, ahora solamente falta graficar el cubo mismo con el método drawTriangles(). Para ello crearemos un Listener que ya sea activado por MOUSE_MOVE, o ENTER_FRAME cualquiera de los dos funcionara bien, pero en este caso utilizare el segundo:
ddEventListener(Event.ENTER_FRAME, eventHandler); // function eventHandler(event:Event):void { switch(event.type) { case Event.ENTER_FRAME: cubo.graphics.clear(); // Borramos la bitmap que haya dentro de "cubo" cubo.graphics.beginFill(0xCA0B45,1); // Fijamos el relleno cubo.graphics.lineStyle(.1,0xA30736,1); // Fijamos también el contorno cubo.graphics.drawTriangles(vertices, aristas, null, TriangleCulling.NEGATIVE); // Utilizamos el método cubo.graphics.endFill(); // Cerramos el relleno } // switch }
Bueno, un cubo aburrido, pero ¿que pasa con la interactividad? Para esto utilizaremos el paquete Matrix3D y Vector3D para poder rotar el cubo en cualquiera de sus tres ejes a base de la posición del cursor:
matrix3D.appendRotation((cubo.y - mouseY)/20, Vector3D.X_AXIS); // Fijamos la rotacion en el eje X matrix3D.appendRotation((cubo.x - mouseX)/20, Vector3D.Y_AXIS); // Fijamos la rotacion en el eje Y Utils3D.projectVectors(matrix3D, points, vertices, UVData); // Añadimos la matrix al cubo
El código resultado seria el siguiente:
var cubo:Sprite = new Sprite(); cubo.x = cubo.y = 100; addChild(cubo); // var matrix3D:Matrix3D = new Matrix3D(); var points:Vector.<Number> = new Vector.<Number>; var vertices:Vector.<Number> = new Vector.<Number>; var aristas:Vector.<int> = new Vector.<int>; var UVData:Vector.<Number> = new Vector.<Number>; var largo:int = 50; // points = Vector.<Number>([ largo, -largo, largo, largo, -largo, -largo, -largo, -largo, -largo, -largo, -largo, largo, largo, largo, largo, largo, largo, -largo, -largo, largo, -largo, -largo, largo, largo ]); // aristas = Vector.<int>([ 2,5,1,3,2,1,5,6,7,7,3,0,1,5,4,2,6,5, 1,4,0,3,6,2,3,7,6,5,7,4,3,1,0,7,0,4 ]); // addEventListener(Event.ENTER_FRAME, eventHandler); // function eventHandler(event:Event):void { switch(event.type) { case Event.ENTER_FRAME: matrix3D.appendRotation((cubo.y - mouseY)/20, Vector3D.X_AXIS); matrix3D.appendRotation((cubo.x - mouseX)/20, Vector3D.Y_AXIS); Utils3D.projectVectors(matrix3D, points, vertices, UVData); // cubo.graphics.clear(); cubo.graphics.beginFill(0xCA0B45,1); cubo.graphics.lineStyle(.1,0xA30736,1); cubo.graphics.drawTriangles(vertices, aristas, null, TriangleCulling.NEGATIVE); cubo.graphics.endFill(); } }
Finalmente, si lo enfocamos hacia su manejo en una clase externa tendremos un resultado parecido a este:
package { // Cargamos los paquetes necesarios... import flash.events.Event; import flash.geom.Matrix3D import flash.geom.Vector3D; import flash.geom.Utils3D; import flash.display.Sprite; import flash.display.TriangleCulling; // public class Main extends Sprite { // La Matrix3D dara la rotacion al cubo private var matrix3D:Matrix3D; // Points sera cada uno de los puntos que ayudaran a acomodar los vértices private var points:Vector.<Number>; // Creo que señalar que formaran estos vectores esta de mas private var vertices:Vector.<Number>; private var aristas:Vector.<int>; // El vector "UVData" obtendra las coordenadas U,V de cada triangulo private var UVData:Vector.<Number>; // "largo" representa el tamaño de "cubo" antes de dibujarlo private var largo:int = 50; private var cubo:Sprite = new Sprite(); // public function Main():void { addChild(cubo); matrix3D = new Matrix3D(); UVData = new Vector.<Number>; vertices = new Vector.<Number>; // Funciones encargadas de fijar los vertices y aristas setPoints(); setLines(); // Añadimos el listener que renderizara el cubo addEventListener(Event.ENTER_FRAME, eventHandler); } // Con esta funcion se van a fijar cada uno de los vertices private function setPoints():void { // Asignamos las posiciones de cada vertice en ejes X,Y,Z points = Vector.<Number>([ largo, -largo, largo, // P1 largo, -largo, -largo, // P2 -largo, -largo, -largo, // P3 -largo, -largo, largo, // P4 largo, largo, largo, // P5 largo, largo, -largo, // P6 -largo, largo, -largo, // P7 -largo, largo, largo // P8 ]); } // Con esta funcion se van a fijar cada uno de los aristas private function setLines():void { // Unimos cada uno de los puntos fijados en la funcion anterior aristas = Vector.<int>([ 2,5,1, // T1: P2-P5-P1 3,2,1, // T2: P3-P2-P1 5,6,7, // T3: P5-P6-P7 7,3,0, // T4: P7-P3-P0 1,5,4, // T5: P1-P5-P4 2,6,5, // T6: P2-P6-P5 1,4,0, // T7: P1-P4-P0 3,6,2, // T8: P3-P6-P2 3,7,6, // T9: P3-P7-P6 5,7,4, // T10: P5-P7-P4 3,1,0, // T11: P3-P1-P0 7,0,4 // T12: P7-P0-P4 ]); } // private function eventHandler(event:Event):void { switch(event.type) { case Event.ENTER_FRAME: // Fijamos las coordenadas del cubo y su rotacion cubo.x = cubo.y = 100; matrix3D.appendRotation((cubo.y - mouseY)/20, Vector3D.X_AXIS); matrix3D.appendRotation((cubo.x - mouseX)/20, Vector3D.Y_AXIS); Utils3D.projectVectors(matrix3D, points, vertices, UVData); // Finalmente "unimos" los puntos para formar el cubo cubo.graphics.clear(); cubo.graphics.beginFill(0xCA0B45,1); cubo.graphics.lineStyle(.1,0xA30736,1); cubo.graphics.drawTriangles(vertices, aristas, null, TriangleCulling.POSITIVE); cubo.graphics.endFill(); } } } }
Una vez dominado el tema, con un poco mas de tiempo se pueden crear figuras mucho mas convincentes cuyas bases son las mismas solo que con 500 vértices mas, y 1000 triángulos:
¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.
Publica tu comentario
El autor de este artículo ha cerrado los comentarios. Si tienes preguntas o comentarios, puedes hacerlos en el foro
Entra al foro y participa en la discusión
o puedes...
¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?
Inicia sesión
¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?
Registrate