Basicamente lo que hace la Clase es ir agregando sobre el mismo eje los angulos correspondientes de cada uno de los Valores introducidos respecto al Total de los mismos...
Como ejemplo, de manera Basica y Minimalista la Clase trabaja asi:..
NOTA: En el siguiente ejemplo no usare la clase, por lo que tal vez paresca mucho rollo hacerlo... Es nada mas para ver su funcionamiento
Creas en el escenario un MC vacio, y en su Instancia lo nombras "Vacio" (por ejemplo...)...
Colocas alineadamente sobre ese MC, otro con Forma de circulo y en su Instancia lo nombras "Mascara"
En el panel de Acciones agregas el siguiente codigo:..
Código :
//- Valores iniciales var Variable:Number = 33; var Total:Number = 120; var Radio:Number = 150;
NOTA:Radio va a ser como su nombre indica el radio de nuestra Grafica a Trazar... Variable va a ser un valor cualquiera siempre y cuando sea menor que Total, Ya que esta representara una fraccion de la Grafica, y la diferencia entre ambas sera la otra fraccion restante... (1/3)
Pero antes de Graficar nescesitamos marcar un angulo(en Radianes), desde el cual empezar y obtener el angulo en Radianes que corresponde a estos dos Valores:..
Ahora viene la parte principal del Codigo, Graficar...
Esto se consigue utilizando las funciones de Seno y Coseno, asi como un poco de conocimientos de Trigonometria para obtener los puntos a Trazar...
Uso correcto de las funciones API de Flash
Código :
//- Obtenemos los puntos que van a Formar el Disco/Moneda/Pastel para la Grafica angInicio = Inicio; angulo1 = Inicio + (angulo/4); angulo2 = Inicio + (angulo/2); angulo3 = Inicio + ((angulo/4)*3); angFinal = Inicio + angulo;
//- Definimos los puntos _x,_y en base al Angulo pInicio_x = Math.cos(angInicio)*Radio; pInicio_y = Math.sin(angInicio)*Radio; punto1_x = Math.cos(angulo1)*Radio; punto1_y = Math.sin(angulo1)*Radio; punto2_x = Math.cos(angulo2)*Radio; punto2_y = Math.sin(angulo2)*Radio; punto3_x = Math.cos(angulo3)*Radio; punto3_y = Math.sin(angulo3)*Radio; pFinal_x = Math.cos(angFinal)*Radio; pFinal_y = Math.sin(angFinal)*Radio;
//- Dibujamos cada una de las Piezas por los puntos ya marcados Vacio.beginFill(0xF3721D,75); Vacio.moveTo(0,0); Vacio.lineTo(pInicio_x, pInicio_y); Vacio.lineTo(punto1_x, punto1_y); Vacio.lineTo(punto2_x, punto2_y); Vacio.lineTo(punto3_x, punto3_y); Vacio.lineTo(pFinal_x, pFinal_y); Vacio.lineTo(0,0); Vacio.endFill();
NOTA: Lo que hace el fragmento de codigo anterior, es buscar los puntos que forman el/los triangulos, basandose en el angulo y el Radio
Finalmente nos queda enmascarar nuestra grafica para que quede mucho mas Estetica:..
Código :
Vacio.setMask(Mascara);
Al final de todo esto nos queda un codigo similar a este:..
Ahora utilizando la Clase, el asunto se simplifica mucho ya que nos da la opcion de incluir cuantos objetos, variables y/o colores quieras, tan solo almacenandolo en un Array...
Por ejemplo:..
Código :
import circleGrafic; var miGrafica:circleGrafic = new circleGrafic ();
//- Definimos el Radio de nuestro circulo var Radio:Number = 125;
//- Uso de los Arrays var Colores:Array = [0xF58F2C, 0xFBEB62, 0xEDC834, 0xEB9B25, 0xF3721D]; var Valores:Array = [295, 116, 56, 16, 75];
//- Utilizamos la Clase para trazar nuestra Grafica de Moneda miGrafica.drawGrafic(Valores, Colores, Radio, this.miContenedor);
NOTA: Como su nombre indica "miContenedor" es el MC en el escenario donde se carga la Grafica
_________________
//- No tengo NPI de que poner aqui... <-- ¿Sugerencias?
Ultima edición por M@U el Sab Ene 05, 2008 3:33 am, editado 1 vez
Creo que sería mucho mejor usar la clase Point y concretamente Polar para hacer la gráfica. Usando la tangente de la polar( cambio de signo a uno de los parámetros) sale el anchor de curveTo y el beginFill va directo y no necesita máscara. Acortaría el código y no necesitas tanto seno y coseno. Bastarian los arrays de definición y la API haria el resto.
Creo que sería mucho mejor usar la clase Point y concretamente Polar para hacer la gráfica[...]
Pero no seria mas pesado el estar creando objetos, mas la llamada de sus funciones ¿?...
Al principio pensaba como tu, pero Point es una clase nativa programada en C++ directamente en el player. Por ende, sus calculos son mucho más veloces que hacerlo nosotros mismos en AS (Incluso AS3)
Pero no seria mas pesado el estar creando objetos, mas la llamada de sus funciones ¿?...
Al principio pensaba como tu, pero Point es una clase nativa programada en C++ directamente en el player. Por ende, sus calculos son mucho más veloces que hacerlo nosotros mismos en AS (Incluso AS3)
Buen punto... Entonces es obvio lo que me queda por hacer...
Por fin deje de araganear, y me puse a buscar como hacerlo segun lo sugerido... Y este es mi resultado:..
Código :
import flash.geom.Point;
//- Creamos todas las variables a usar var Angle:Array = new Array(); var Values:Array = [295, 112, 76, 51, 13]; var ArrayLength:Number = Values.length -1; var radian:Number = 2 * Math.PI; var allValues:Number = 0;
//- Utilizamos for para determinar los angulos correspondientes a cada valor for(var i:Number = 0; i < Values.length; i++){allValues += Values[i];} for(var i:Number = 0; i < Values.length; i++){Angle[i] = (Values[i]/allValues)*(2*Math.PI);}
//- Creamos la funcion encargada de redondear los Valores introducidos function roundNumber(number:Number){ var newNumber:Number = Math.round(number*10); return Number(newNumber /10);}
//- Creamos la funcion encargada de Graficar function circleGrafic(Values:Array, point:Point, radius:Number){lineStyle(0); moveTo(point.x + radius, point.y); for(var i:Number = 0; i <= radian; i += radian / 360){ if(roundNumber(i) == roundNumber(Angle[ArrayLength])){lineTo(point.x, point.y); ArrayLength--;} polarPoint = point.add(Point.polar(radius,i)); lineTo(polarPoint.x, polarPoint.y);}}
//- Finalmente la llamamos circleGrafic(Values, new Point(75, 75), 50);
Son muchas menos lineas, ademas de que se volvio mas ligero el archivo...
_________________
//- No tengo NPI de que poner aqui... <-- ¿Sugerencias?
Prueba a desarrollar sobre este código base: (creo que funcione, lo he hecho al vuelo y sin el flash abierto) -No pongo las declaraciones estrictas de hecho en Flash 8, y para este caso,no sirven de nada. -El asterisco del import cargará solo lo necesario de modo que no aumenta el tamaño del swf.
Código :
import flash.geom.*;
function tarta(centroX, centroY, radio, Acolor, Avalor){ angulo = 0; suma = 0; vlen = Avalor.length; Pc = new Point(centroX, centroY); for (n=0; n < vlen; n++)suma += Avalor[n]; ratio=2*Math.PI/suma; P2 = new Point(Pc.x + radio, Pc.y); for (n=0; n < vlen; n++){ ang2 = Avalor[n]*ratio/2; while(ang2>.001){ ang3 = ang2>.5 ? .5 : ang2; ang2 -=.5; this.beginFill(Acolor[n],100); this.moveTo(Pc.x, Pc.y); this.lineTo(P2.x, P2.y); Pa = Pc.add(Point.polar(radio/Math.cos(ang3),angulo+ang3)); angulo += 2*ang3; P2 = Pc.add(Point.polar(radio,angulo)); this.curveTo(Pa.x,Pa.y,P2.x,P2.y); this.endFill(); } } }
No alcanzo a ver la diferencia entre ambos codigos que posteaste... Aqui no tengo Flash ni nada parecido instalado, pero aseguro que los checare a detalle en casa... Muchas Gracias desde ya Teseo...
_________________
//- No tengo NPI de que poner aqui... <-- ¿Sugerencias?
Ultima edición por M@U el Mie Ene 09, 2008 4:09 am, editado 1 vez
Son muy similares. Unicamente que no es necesario un array para los ángulos ni el redondeo de los valores. Tampoco necesita un bucle de 360 pasos, usa uno con muchos menos creando arcos (curveTo) ni la constante de radianes al utilizar ese valor solo una vez en el cálculo del ratio.
Son muy similares. Unicamente que no es necesario un array para los ángulos ni el redondeo de los valores. Tampoco necesita un bucle de 360 pasos, usa uno con muchos menos creando arcos (curveTo) ni la constante de radianes al utilizar ese valor solo una vez en el cálculo del ratio.
Muy interesante realmente... Lo del colorear cada fragmento, y el codigo para que no se salteara partes ya lo habia solucionado... Pero admito que tu codigo es superior...
_________________
//- No tengo NPI de que poner aqui... <-- ¿Sugerencias?
Esta es una versión del código anterior ampliada para poder ordenar la salida, el angulo inicial y colocar cada sector en un MC de modo que podamos añadir (a cada sector) filtros, textos-tip, etc... así como moverlos, escalarlos, rotarlos o recolocarlos independientemente mediante cualquier evento.
Código :
import flash.geom.*;
function tarta(centroX, centroY, radio, Acolor ,Avalor, angulo, orden){ //angulo: origen del primer valor de la tarta en grados; si es null o no se pasa angulo usa eje vertical // orden: 0 como vienen en el array; 3 orden descendente; sin pasar ó 1 ó 2 orden ascendente. angulo = angulo ? angulo*Math.PI/180 : -Math.PI/2; suma = 0; ttclip=[]; GF= new flash.filters.BevelFilter();// creado por defecto, se puede personalizar al gusto: //GF.highlightColor= 0xeeeeee; GF.distance= 3; // etc... Avalor.sort(16|orden-1); vlen = Avalor.length; Pc = new Point(centroX, centroY); for (n=0; n < vlen; n++)suma += Avalor[n]; ratio=2*Math.PI/suma; P2 = Pc.add(Point.polar(radio,angulo)); for (n=0; n < vlen; n++){ ang2 = Avalor[n]*ratio/2; ttclip[n] = this.createEmptyMovieClip("tartaclip", this.getNextHighestDepth()); while(ang2>.001){ ang3 = ang2>.5 ? .5 : ang2; ang2 -=.5; ttclip[n].beginFill(Acolor[n],100); ttclip[n].moveTo(Pc.x, Pc.y); ttclip[n].lineTo(P2.x, P2.y); Pa = Pc.add(Point.polar(radio/Math.cos(ang3),angulo+ang3)); angulo += 2*ang3; P2 = Pc.add(Point.polar(radio,angulo)); ttclip[n].curveTo(Pa.x,Pa.y,P2.x,P2.y); ttclip[n].endFill(); ttclip[n].filters =[GF]; } } }
Bravisimo ! Aprendi bastante aqui... Admito que pensaba optimizar el codigo del principio (cosa que sucedio poco a poco cambiando radicalmente su manera de funcionar), para subirlo como Tip agradeciendo a quienes colaboraron (Teseo por ejemplo...) ...
Pero ahora se hizo una obra maestra que no esperaba; de la cual no me considero su Autor Intelectual... La clase optimisada, la subire mañana temprano... Y despues que hago con todo esto ¿?... Alguna idea ¿?...
_________________
//- No tengo NPI de que poner aqui... <-- ¿Sugerencias?
La idea es tuya. Yo sugerí usar polar point y lo resolviste bastante bien. Evidentemente el trabajo es tuyo, te lo curraste y si construiste la clase.. pues perfecto!! Presenta el tip. Es, desde su origen, cosa tuya.
La manera de uso de la clase, es muy sencillo... Y la puedes descargar de Aqui.
Código :
//- Primero que nada, importamos; //- En este caso la clase se encuentra al mismo nivel que el *swf import customGrafic; var miGrafica:customGrafic = new customGrafic (); //- Definimos el Radio de nuestro circulo var Radio:Number = 85; //- Creamos un Array para los colores a utilizar var Colores:Array = [0xF58F2C, 0xFBEB62, 0xEDC834, 0xEB9B25, 0xF3721D]; //- Creamos un Array para los valores de las cajas de texto var Valores:Array = [295, 116, 56, 15, 75];
Finalmente utilizamos la funcion dentro de la Clase...Para ello debe tener el siguiente orden:...
Los primeros 2 valores son las coordenadas en _x y _y, respectivamente
El segundo valor es el Radio que tendra nuestra grafica
El tercer valor es el Array que almacena cada uno de los colores
Finalmente, el cuarto valor es el Array con las cantidades que corresponden a cada Color respectivamente
Código :
//- Si todo esta como debe creamos una nueva Grafica de Moneda miGrafica.drawGrafic(100, 100, Radio, Colores, Valores);
Prueba de la Clase
_________________
//- No tengo NPI de que poner aqui... <-- ¿Sugerencias?