Comunidad de diseño web y desarrollo en internet online

Expluir Poligono dentro de otro poligono... mediante codigo!

Citar            
MensajeEscrito el 05 Ago 2008 10:57 am
Hola a todos,

En primer lugar decir que llevo un tiempo entrando y formandome en este foro. Muchas gracias a todos...

Por otro lado, tengo un problema que no se muy bien como solucionar:

Tengo que pintar una zona geografica (formada por varios poligonos), adicionalmente dentro de cada poligono puede haber exclusiones que pertenecen a otras zonas geograficas o no.(poligonos de exclusion).
Para cada zona tengo que hacerla Over al pasar por encima.

Claro decir que cargo las zonas de un XML y que son muchas y no solamente eso si no que no tengo manera de controlar el orden.

Ahora mismo estoy pintando los poligonos en dos movieclip, normales y de exclusion, pero no se como mezclarlos para que hagan su cometido.

Espero que alguien me ayude.. Gracias
PD: Lo siento por toda la parrafada.

Por earenas

5 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 05 Ago 2008 11:00 am
Los de exclusión tienen que estar en un nivel superior a las zonas que lo contienen, luego puedes hacer rollOver sobre cualquiera de ellos

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 05 Ago 2008 11:03 am

solisarg escribió:

Los de exclusión tienen que estar en un nivel superior a las zonas que lo contienen, luego puedes hacer rollOver sobre cualquiera de ellos
Jorge


Eso esta claro, pero creo que me explique mal...
Llos de exclusion taparan otras zonas que esten por debajo de estas...
Cada zona esta a su vez metida dentro de un movieclip...

Lo que necesito es algo asi como una mascara inversa.. osea teniendo un poligono, hacer desaparecer parte del el... vamos que para el moviclip de zona.. no exista las exclusiones y que si hay algo por debajo lo trate... como por ejemplo un rollover de otra zona...

espero haberme explciado bien...
Saludos!

Por earenas

5 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 05 Ago 2008 11:11 am
La verdad no lo entiendo bien, pero no hay máscara inversa (en todo caso aplicariías la máscara a otro elemento) y el orden del stack es mandatorio en los eventos de Mouse, a menos que hagas setChildIndex de alguna forma para jugar con el stack, no puedes tener un MouseOver arriba y un MouseOver abajo, lo tienes en el orden que tengas tus elementos en el DisplayList

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 05 Ago 2008 11:27 am
La idea es quitar de un poligono que esta echo con un sprite una zona interior de el... en gui seria facil pues haces el poligono... y luego borras parte de el...

El problema es que tengo algo asi como 100.000 zonas... que tienen n poligonos cada una.. algunas con n poligonos de exclusion...

Partiendo que algunas zonas se solapan entre ellas (tengo marcadas con las zonas de exclusion) ...

Por otra aprte, no puedo saber el orden de pintado ya que eso complicaria mucho el algoritmo (tiempo de carga) al ser tantas zonas.

Por earenas

5 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 05 Ago 2008 11:43 am
No entiendo bien lo que pides, parece que hará falta alguna imagen para explicarlo, es que está un poco enredado.

Por elchininet

Claber

3921 de clabLevel

17 tutoriales

Genero:Masculino  

Front-end developer at Booking.com

firefox
Citar            
MensajeEscrito el 05 Ago 2008 12:48 pm


Lo que hace:

1º Crea movieclip para la zona 1 ("B01920")
2º Pinta los poligonos amarillo... debajo de lo azul hay 3 poligonos más pertenecientes a esta zona.
3º Crea el rollOver para la zona 1 (solo lo amarillo).
4º Crea un movieclip para la zona 2
5º Pinta la zona roja de esta zona(como veis son 3 poligonos separados).
6º Pinta la zona azul (exclusiones) dentro de uno de los poligonos (solapando la zona 1 )
7º Creo el rollOvel para la zona 2 (solo lo rojo).

No se si ha quedado claro el proceso....
Pero al pintar la el poligono rojo y luego las zonas de exclusion (azul) solapa la zona 1 (amarillo) imposivilitando en rollOver de ella)...
Si se pudiera pintar el poligono y excluir (borrar o lo que sea) la zona azul.. se veria lo que hay debajo... Vamos algo asi como borrar con la goma en el GUI.

Esto se podria conseguir con algun algoritmo para procesar los solapados, pero al tener miles y miles de zonas... se complica mucho y el tiempo de carga se hace infinito...

Saludos, Eduardo

Por earenas

5 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 05 Ago 2008 05:12 pm
Ahh ya veo lo que quieres hacer, hace algún tiempo quise hacer algo como eso y encontré en la web una manera que era convirtiendo el objeto enmascarador a bitmap y después aplicándole un threshold, pero no me agradó porque el treshold tomaba todos los píxeles de color y los convertía a transparentes, por lo que desaparecía el antialiasing de los bordes. Pero quizás a ti te saque del aprieto, utiliza esta clase, ponla en el mismo lugar donde tengas tu flash y prueba el siguiente script para que veas el resultado:

Clase:

Código :

package {
   
   import flash.display.DisplayObject;
   import flash.display.DisplayObjectContainer;
   import flash.display.Sprite;
   import flash.geom.ColorTransform;
   import flash.geom.Matrix;
   import flash.geom.Rectangle;
   import flash.geom.Point;
   import flash.display.BitmapData;
   import flash.display.Bitmap;
   
   public class deleteClip{
      
      private var _displayObj:DisplayObject;
      
      //---Función principal
      public function deleteClip(obj:DisplayObject){
         
         _displayObj = obj;
         
      }
      
      //---Función de crear la máscara
      public function deleteExclusion(masked:DisplayObject):Sprite{
         
         masked.cacheAsBitmap = true;
         
         var bitmap:BitmapData = new BitmapData(masked.width, masked.height);
         var exclusion:ColorTransform = new ColorTransform(0, 0, 0, 1, 0, 0, 0);
         var exclusionMatrix:Matrix = new Matrix();
         exclusionMatrix.translate(_displayObj.x, _displayObj.y);         
         
         var exclusionRectangle:Rectangle = new Rectangle(0, 0, bitmap.width, bitmap.height);
         var exclusionPoint:Point = new Point(0, 0);
         
         bitmap.draw(_displayObj, exclusionMatrix, exclusion);
         
         bitmap.threshold(bitmap, exclusionRectangle, exclusionPoint, "<", 0xFFFFFFFF);
         
         var excludeBitmap:Bitmap = new Bitmap(bitmap, "auto", true);
         
         var exclusionMc:Sprite = new Sprite();
         exclusionMc.addChild(excludeBitmap);
         exclusionMc.cacheAsBitmap = true;
         
         masked.parent.addChild(exclusionMc);
         exclusionMc.visible = false;
         return exclusionMc;
         
      }      
      
   }
   
}


Código en el flash

Código :

var fondo:Sprite = new Sprite();

fondo.x = 100;
fondo.y = 100;

with(fondo.graphics){
   
   beginFill(0xCCCCCC, 1);
   drawRect(0, 0, 300, 300);
   endFill();
   
}


//---Zona 2
var zona2:Sprite = new Sprite();

with(zona2.graphics){
   
   beginFill(0x0000FF, 1);
   drawRect(0, 0, 300, 300);
   endFill();
   
}

//---Exclusión
var exclusion:Sprite = new Sprite();

exclusion.x = 100;
exclusion.y = 100;

with(exclusion.graphics){
   
   beginFill(0xFF0000, 1);
   drawCircle(0, 0, 50);
   endFill();
   
}

addChild(fondo).name = "fondo";
addChild(zona2).name = "zona2";

var clipToDelete:deleteClip = new deleteClip(exclusion);
zona2.mask = clipToDelete.deleteExclusion(zona2);


si pudieras al bitmap que se crea no aplicarle threshold, si no convertir todos los pixeles de color a transparentes pero con su respectivo canal alpha quizás logres un antialiasing, yo lo intenté pero no lo logré.

Por elchininet

Claber

3921 de clabLevel

17 tutoriales

Genero:Masculino  

Front-end developer at Booking.com

firefox
Citar            
MensajeEscrito el 06 Ago 2008 06:58 am
¿ y con BlendMode?, ya no sé si servirá el BlendMode.ERASE o el BlendMode.ALPHA
http://livedocs.adobe.com/flash/9.0_es/ActionScriptLangRefV3/flash/display/DisplayObject.html#blendMode

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 06 Ago 2008 09:18 am

Eliseo2 escribió:

¿ y con BlendMode?, ya no sé si servirá el BlendMode.ERASE o el BlendMode.ALPHA
http://livedocs.adobe.com/flash/9.0_es/ActionScriptLangRefV3/flash/display/DisplayObject.html#blendMode

Con BlendMode ya lo intente pero sin resultado... ademas de que tienes que tener un fondo debajo con BlendMode.LAYER y eso me cierra la posibilidad de recoger eventes de clips que esten por debajo... Pero aun asi, no consegui el efecto deseado...

Gracias elchininet por el tip, de echo asi por lo menos consigo el efecto visual que queria... ahora ya se ven las zonas inferiores como debe de ser... bueno tengo un problema con el tamaño del bitmap que no se muy bien porque no pilla el tamaño completo... sino parte de el...

De todas maneras elchininet, el problema sigue siendo recoger eventos de elementos que esten por debajo de el... en tu ejemplo:

Código :

var fondo:Sprite = new Sprite();

fondo.x = 100;
fondo.y = 100;

with(fondo.graphics){
   
   beginFill(0xCCCCCC, 1);
   drawRect(0, 0, 300, 300);
   endFill();
   
}
fondo.addEventListener(MouseEvent.MOUSE_OVER, fondoOver);
fondo.addEventListener(MouseEvent.MOUSE_OUT, fondoOut);


//---Zona 2
var zona2:Sprite = new Sprite();

with(zona2.graphics){
   
   beginFill(0x0000FF, 1);
   drawRect(0, 0, 300, 300);
   endFill();
   
}

//---Exclusión
var exclusion:Sprite = new Sprite();

exclusion.x = 100;
exclusion.y = 100;

with(exclusion.graphics){
   
   beginFill(0xFF0000, 1);
   drawCircle(0, 0, 50);
   endFill();
   
}

addChild(fondo).name = "fondo";
addChild(zona2).name = "zona2";

var clipToDelete:deleteClip = new deleteClip(exclusion);
zona2.mask = clipToDelete.deleteExclusion(zona2);

zona2.addEventListener(MouseEvent.MOUSE_OVER, zona2Over);
zona2.addEventListener(MouseEvent.MOUSE_OUT, zona2Out);

function fondoOver(e:MouseEvent):void{
   fondo.bgTransform(0x00FF00,.5);
}
function fondoOut(e:MouseEvent):void{
   fondo.bgTransform(0xCCCCCC,.5);
}
function zona2Over(e:MouseEvent):void{
   zona2.bgTransform(0x00FF00,.5);
}
function zona2Out(e:MouseEvent):void{
   zona2.bgTransform(0x0000FF,.5);
}

En la zona donde "borramos" no podemos capturar el evento del fondo...
¿Habria alguna solucion para esto?

Saludos!

Por earenas

5 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 06 Ago 2008 12:13 pm
Buaf, eso no se puede hacer ni con máscaras tradicionales, porque es que cuando dás eventos al clip zona2 este evita que los de abajo de él tengan eventos y para flash, zona2 no tiene un orificio, este orificio es solamente visual.

Por elchininet

Claber

3921 de clabLevel

17 tutoriales

Genero:Masculino  

Front-end developer at Booking.com

firefox
Citar            
MensajeEscrito el 06 Ago 2008 12:31 pm

elchininet escribió:

Buaf, eso no se puede hacer ni con máscaras tradicionales, porque es que cuando dás eventos al clip zona2 este evita que los de abajo de él tengan eventos y para flash, zona2 no tiene un orificio, este orificio es solamente visual.


Entiendo... Es una putada que no se pueda hacer de la misma manera que se hace en modo GUI, si a un cuadrado le borrar con la gona en medio de el... el resultado es un agujero real... Como el que yo tendria que conseguir :D

Entonces voy a hacer un array de indices (a modo de grid para controlar zonas) para que si se hace rollOver sobre una exclusion ( zona transparente por encima de todo, a parte de la mascara para crear el efecto visual), cheke a ver si toca algun otra zona ( que no zonas de exclusion)... con los indices acorto las zonas a mirar en el algoritmo... otra cosa no se me ocurre

¿¿teneis alguna otra idea?

Eduardo

Por earenas

5 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 07 Ago 2008 06:34 am
Tengo la idea de que cuando haces un MouseDown, se transmite a todos los objetos que tengas debajo, Lo que se dice "propagación de eventos" (que, por supuesto, lo explican mejor aquí)
http://www.learningactionscript3.com/2007/11/10/event-phases-in-action/

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 07 Ago 2008 12:57 pm
Esto es muy sencillo de hacer cuando los objetos que están dentro son más pequeños que el contenedor y están ubicados uno encima de otro en orden descendente, el problema que lo que se propone @earenas es que (tomando el ejemplo del link) medium folder y samall folder estén por detrás de bigFolder y bigfolder tenga una máscara que visualmente cree un orificio y deje ver a smalFolder y mediumFolder, pero esta máscara no impedirá que todos los eventos los tome bigfolder, ya que este está ocultando a los demás.

Por elchininet

Claber

3921 de clabLevel

17 tutoriales

Genero:Masculino  

Front-end developer at Booking.com

firefox
Citar            
MensajeEscrito el 08 Ago 2008 09:22 am
Exacatamente eso me ocurre.. aqui los elementos no estan anidados uno dentro del otro por tanto es imposible hacer propagación de eventos...
De todas maneras el ejemplo me ha servido para sacar un unico evento y tratarlo desde la capa mas baja, asi tarda algo menos en cargar y tengo un solo evento, por los miles que tenia para cada zona...
La solucion la estoy tratando creando una especie de grid, guardo en un array las zonas por su tamaño y colocación. Luego al hacerse evento sobre un poligono de exclusión, busco en el grid que elementos estan dentro de esa zona y busco el solapado (si lo hay )...

De todas formas, es algo tardado pues tengo que buscar poligono de cada zona, en que cuadrates esta para guardarlo en el array a modo de grid....

Si hay alguna otra manera.... mas eficiente, agradeceria consejos...

Saludos!

Por earenas

5 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 08 Ago 2008 12:15 pm
Bueno seguimos con los problemas.. y es que no se porque, el hitTestPoint no funciona,

¿puede ser que sea porque tambien estoy haciendo un escalado aunque los puntos esten correctos?

Se me estan acabando las ideas y la paciencia... :twisted:

Saludos!

Por earenas

5 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 08 Ago 2008 02:21 pm
Si tienes un movie con una máscara y le aplicas hitTest, lo que recibirá hitTest es el movie original no lo que ves después de enmascarar. (Lo mismo que los eventos)

Por elchininet

Claber

3921 de clabLevel

17 tutoriales

Genero:Masculino  

Front-end developer at Booking.com

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.