Test Foro de elhacker.net SMF 2.1

Programación => Programación General => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: AlexPro en 7 Julio 2012, 22:43 PM

Título: Perfect Pixel Collision ayuda
Publicado por: AlexPro en 7 Julio 2012, 22:43 PM
Hola, he hecho el siguiente método para comprobar si colisionan dos imagenes por los pixeles:
Código (csharp) [Seleccionar]
       private bool CheckPixelCollision(int Image1_x, int Image1_y, int Image2_x, int Image2_y, Bitmap Image1, Bitmap Image2)
       {
           bool intersected = false;
           
          for (int i = 0; i < Image1.Width; i++)
          {
              for (int j = 0; j < Image1.Height; j++)
              {
                 
                  for (int k = 0; k < Image2.Width; k++)
                  {
                      for (int l = 0; l < Image2.Height; l++)
                      {
                          Color Image1_color = Image1.GetPixel(i, j);
                          Color Image2_color = Image2.GetPixel(k, l);
                          if (Image1_color.A != 0 & Image2_color.A != 0)
                          {
                              if (Image1_x+i == Image2_x+k & Image1_y+j == Image2_y+l)//Vemos si colisionan los pixeles
                              {
                                  intersected = true;
                                 
                                 
                              }
                          }
                      }
                  }
              }
          }

El código funciona y devuelve true, el problema es que el programa va muy lento cuando se ejecuta esta función. Alguien tiene otra forma de hacer Perfect Pixel Collision?
PD: utilizo gdi+ para el código
Título: Re: Perfect Pixel Collision ayuda
Publicado por: AlexPro en 8 Julio 2012, 12:06 PM
Lo he conseguido corregir de la siguiente forma... Saludos
Código (csharp) [Seleccionar]
//Metodo para ver si colisionan dos objetos según los píxeles
        private bool CheckPixelCollision(int Image1_x, int Image1_y, int Image2_x, int Image2_y, Bitmap Image1, Bitmap Image2)
        {
            bool intersected = false;//Por defecto no colisionaran
           
            //Se va a realizar la comprobación píxel por píxel
           for (int i = 0; i < Image1.Width; i++)
           {
               for (int j = 0; j < Image1.Height; j++)
               {
                   Color Image1_color = Image1.GetPixel(i, j);
                   if (Image1_color.A != 0)//Se comprueba primero si el pixel de la imagen 1 no es transparente
                   {

                       for (int k = 0; k < Image2.Width; k++)
                       {
                           if (Image1_x + i == Image2_x + k)//Vemos si colisionan los pixeles
                           {
                               for (int l = 0; l < Image2.Height; l++)
                               {

                                   Color Image2_color = Image2.GetPixel(k, l);
                                   if (Image2_color.A != 0)//Comprobamos si no es transparente el píxel de la imagen 2
                                   {
                                       if (Image1_y + j == Image2_y + l)//Vemos si colisionan los pixeles
                                       {
                                           intersected = true;


                                       }
                                   }

                               }
                           }
                       }
                   }
              }
           }

           if (intersected == true)
           {
               return true;//Devuelve true si colisionan
           }
           else
           {
               return false; //Si no colisionan devuelve false
           }



       
           
        }
Título: Re: Perfect Pixel Collision ayuda
Publicado por: Keyen Night en 17 Julio 2012, 00:41 AM
¿Colisionan en que sentido?, porque tienes la Clase Region, que tiene una función para obtener los rectángulos que la conforman de una manera muy precisa y luego realizarle a cada rectángulo .Contains para verificar que existe un par de coordenadas en su área.

La recursividad nunca es el mejor camino, imagina una imagen de 1000x1000 a compararse con otra de 500x500.

Serían 250 mil millones de vueltas del bucle :S
Título: Re: Perfect Pixel Collision ayuda
Publicado por: AlexPro en 17 Julio 2012, 16:10 PM
Gracias, lo tendré en cuenta.
Un saludo.
Título: Re: Perfect Pixel Collision ayuda
Publicado por: spiritdead en 17 Julio 2012, 17:16 PM
te recomiendo usar poligonos rectangulares y ecuaciones de interseccion de rectas
por ahi mas o menos deberias ir dandole

por ciclos lo que haras es saturar el CPU y consumiras mas RAM y por lo tanto tu app sera mas lenta a la larga
Título: Re: Perfect Pixel Collision ayuda
Publicado por: Keyen Night en 17 Julio 2012, 23:45 PM
Si las imágenes A y B tienen una posición X y Y y un alto y ancho, una intercepta a la otra siempre que el rectángulo formado por alguna de las 2 imágenes contenga al menos un punto del rectángulo de la imagen contraria.

De no ser posiciones rectangulares es que se complica más, ahora escribo un código de ejemplo para que se vea con mayor claridad.

Aquí esta es un proyecto vació de WindowsForm el siguiente código:

Código (vb.net) [Seleccionar]
Imports System.Drawing.Drawing2D

Public Class Form1

   Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

       Dim A As New GraphicsPath
       Dim B As New GraphicsPath

       'Las coordenadas y tamaños son solo de ejemplo'
       A.AddRectangle(New Rectangle(10, 50, 100, 200))
       B.AddRectangle(New Rectangle(30, 69, 200, 100))

       'Se dibujan los rectangulos de ejemplo'
       e.Graphics.FillPath(Brushes.Green, A)
       e.Graphics.FillPath(Brushes.Red, B)

       'Se guardan las regiones de los rectangulos'
       Dim RegionA As New Region(A)
       Dim RegionB As New Region(B)

       'Se guarda en RegionA la intercepción que existe entre A y B'
       RegionA.Intersect(RegionB)

       'Se pinta la region intercepta'
       e.Graphics.FillRegion(Brushes.Blue, RegionA)

       Dim Punto As PointF = RegionA.GetBounds(e.Graphics).Location

       'Si la region no esta vacia, entonces estamos en presencia'
       'de una intercepcion, ya que hemos logrado pintarla'
       If Not RegionA.IsEmpty(e.Graphics) Then
           e.Graphics.DrawString("Intercepción", Me.Font, Brushes.Red, Punto.X, Punto.Y)
       End If

   End Sub

End Class