Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





¿como Hacer Esto?

Iniciado por SrDurden, 24 de Septiembre de 2004, 07:44:14 PM

« anterior - próximo »

ethernet

 puedes usar un perlin y después aplicarle una función no lineal tipo x^2 o x^3

un saludo

SrDurden


SrDurden

 He estado leyendo sobre perlin.. ¿Es un tipo de ruido, verdad?

Teniendo en cuenta que lo único que quiero es suavizar un poco los bordes.. me saldría a cuenta utilizar el perlin noise?

Aparte que únicamente utilizo dos colores.. ¿Vale la pena?

Y.. ¿alguien me podría explicar de manera sencilla en que consiste?

Saludotes! (mola)

PD=Alguien sabe pq no puedo por ejemplo editar el mensaje anterior?

Sacrifai

Cita de: "SrDurden"PD=Alguien sabe pq no puedo por ejemplo editar el mensaje anterior?
Cuando pasan 15 minutos no te deja  ;) .


ethernet

 Me refería a obtener el terreno mediante perlin aunque yo creo que la base que tienes hecha está muy bien. Busca info de filtros (como bien te dijo seryu), es muy fácil hacer uno promediador por ejemplo

saludos y ánimo

Pogacha

 for (WORD jy=479; jy>0; jy-- ) {
   for (WORD ix=639; ix>0; ix-- ) {
if (jy<350) { if (ColorPixel(ix,jy+1)==0xFFFF) PutPixel(ix,jy,0xFFFF);
if ((rand()%3==1)&&(ix<639)&&(ColorPixel(ix+1,jy+1)==0xFFFF)) { PutPixel(ix,jy,0xFFFF); PutPixel(ix-1,jy,0xFFFF); }
if ((rand()%3==1)&&(ix>0)&&(ColorPixel(ix-1,jy+1)==0xFFFF)) { PutPixel(ix,jy,0xFFFF); PutPixel(ix+1,jy,0xFFFF); }

else { if (rand()%9000==1)  PutPixel(ix,jy,0xFFFF);  } }
 
}

Algunos tips:
Cuidado con ix>0 del for, jamas escribes en ix=0 y tampoco en jy=0
te queda una linea salteada a la izquierda y arriba
Tambien es estandart llamar i, j y k a las variables de un bucle.

En realidad el codigo es original, pero bastante raro tambien.

Te sugiero:
Para empezar solo te interesa la altura del terreno, con lo que puedes agarrarte mejor con
una tabla de alturas.

Este codigo lo escribí al vuelo, pero creo te será util.

int TablaDeAlturas[Resolucion_X];

for(int i=0; i<Resolucion_X; i++) TablaDeAlturas[i]=rand()%Resolucion_Y;

//  algun tipo de filtro
//  este es de lo mas torpe, puedes investigar al respecto
for(j=0; j<10; j++) // j variable muda de iteración, variando esto deberia variar la redondez.
{
 for(i=1; i<Resolucion_X-1; i++)
 {
   TablaDeAlturas[i+1]+=TablaDeAlturas[i];
   TablaDeAlturas[i-1]+=TablaDeAlturas[i];
 }
 for(i=0; i<Resolucion_X; i++)  TablaDeAlturas[i]/=3; // promedia las alturas
}

for(i=0; i<Resolucion_X; i++)
{
 // Lo ideal es usar lineas
 // Line(i, 0,i, TablaDeAlturas[i], 0xFFFF);
 // Line(i, TablaDeAlturas[i]+1, i, Resolucion_Y-1 , 0x0000);

// pero lo haremos poniendo pixels
  for(j=0; j<TablaDeAlturas[i]; j++) PutPixel(i,j,0xFFFF);
  for(; j<Resolucion_Y; j++) PutPixel(i,j,0x0000);
}

SrDurden

 Pochaga, gracias por el aviso del >, no me había dado cuenta, cosa de las prisas :P Lo de ix y jy fue por las prisas, en principio iba a ser i y j como toda la vida  ;)

Me ha gustado la idea de la tabla de alturas y el suavizado, con el código a saco se me sale de rango en alguna parte, pero mañana me pondré a buscar por donde me está petando :P

Con unas modificaciones del código de ayer hoy he conseguido esto:



Pero igualmente mañana probaré lo de la tabla de altura con el suavizador por promedio, me ha gustado la idea :P

Saludotes y gracias a todos,

SrDurden (mola)

PD=EDIT: Con lo que me has dicho y la imagen que he colgado, me he dado cuenta que me olvido dos pixeles a la derecha, uno encima y otro a la izquierda! Esas mates y esas prisas, jeje

Pogacha

  for(i=1; i<Resolucion_X-1; i++)
{
  TablaDeAlturas[i+1]+=TablaDeAlturas[i];
  TablaDeAlturas[i-1]+=TablaDeAlturas[i];
}

Hablando de prisas, eso nunca puede andar bien.
Tenes que usar un double buffer para eso



int TablasDeAltura[Resolucion_X][2];
... // escries en TablasDeAltura[i][0] y luego
for j ...
for(i=1; i<Resolucion_X-1; i++)
{
  TablaDeAlturas[i+1][j&1]+=TablaDeAlturas[i][(j+1)&1];
  TablaDeAlturas[i-1][j&1]+=TablaDeAlturas[i][(j+1)&1];
}
...
...
}

Saludos

SrDurden

 No entiendo pq se tiene que utilizar un double buffer..

y que es TablaDeAlturas[i+1][j&1]+=TablaDeAlturas[(j+1)&1]; ? y que es ese &1?

Saludotes,

SrDurden  :(  

Pogacha

 Perdon por la confución que te cause. Aver si logro enmendar el error.
Si hago:
for(i=1; i<100; i++) t[i]+=t[i-1];
estoy haciendo:

t[1] = t[1] + t[0]

En el siguiente ciclo:

t[2] = t[2] + t[1]  y como t[1] es ahora t[1] + t[0]

t[2] = t[2] + t[1] + t[0]

y asi

t[99]= t[99] + t[98] + t[97] + ... + t[0]

por eso es que no funciona, yo quiero que a cada elemento se le sumen los dos vecinos.

por eso mencione un doble buffer.

Un doble buffer consiste en tener dos tablas, una de escritura y otra de lectura

int Tabla1[100];
int Tabla2[100];

entonces leo los datos de la tabla 1 y los escribo en la tabla 2 y asi evito el acumulamiento.

Tabla2 = (Tabla1[i-1] + Tabla1 + Tabla1[i+1]) /3;

Luego los datos actuales que tengo quedan en la tabla 2.
y para vover a repetir el proceso debo

usar leer ahora en la tabla 2 y escribir en la tabla 1.

Tabla1 = (Tabla2[i-1] + Tabla2 + Tabla2[i+1]) /3;

Pero esto significa repetir el codigo que en definitiva es el mismo, por eso uso un arreglo bidimenisonal de esta manera

int Tabla[100][2];

cuando trabajo la primera vez me referire con el indice 0 a la tabla 1 y con el indice 1 a la tabla 2, ya que el c tiene como primer indice el 0 a diferencia del pascal que comienza con el 1

entonces me resulta de
...
Tabla[1] = (Tabla[i-1][0] + Tabla
  • + Tabla[i+1][0]) /3;
    ...
    Tabla
    • = (Tabla[i-1][1] + Tabla[1] + Tabla[i+1][1]) /3;
      ...

      lo cual puedo arreglar como

      int Destino=1;
      int Origen=0;
      ...
      Tabla[Destino] = (Tabla[i-1][Origen] + Tabla[Origen] + Tabla[i+1][Origen]) /3;
      ...
      Destino = 0;
      Origen= 1;

      ...
      Tabla[Destino] = (Tabla[i-1][Origen] + Tabla[Origen] + Tabla[i+1][Origen]) /3;
      ...

      pero como vemos solo invierto los origen y destino asi que en muchas pasadas puedo calcular el valor de destino y origen cada vez.

      si analizamos los numeros binarios:
      0 =   0 B
      1 =     1 B
      2 =    10 B
      3 =    11 B
      4 =  100 B
      5 =  101 B
      6 =  110 B
      7 =  111 B

      Vemos que el utlimo bit se alterna entre 0 y 1, por eso al realizar la operacion logica AND ( & ), tenemos un filtrado del numero y me deja solo si es par o no.

      23 & 1 = 1
      12345 & 1 = 1
      12342 & 1 = 0
      12349 & 1 = 1
      2340 & 1 = 0
      2346 & 1 = 0


      con esto puedo generar el origen y destino preguntando si es no es par el numero de la pasada.

      for(j=0; j<Numero_de_pasadas; j++)
      {
        if(j & 1)
        {
          Origen = 1;
          Destino =0;
        } else {
          Origen = 1;
          Destino =0;
       }

       for(i=1; i<99; i++);
        Tabla[i][Destino] = (Tabla[i-1][Origen] + Tabla[i][Origen] + Tabla[i+1][Origen]) /3;
      }

      y tambien como veras:

      cuando j & 1 = 1  se cumple que Origen = 1 y cuando j & 1 = 0 se cumple de la misma manera que Origen = 0 por ende se deduce que Origen = j & 1;
      Para destino es facil, destino vale 0 cuando origen vale 1 y 1 viceversa, de esta manera podemos decir que Destino = (j+1) & 1 de esta manera cuando j sea para j+1 sera par.

      Entonces:

      for(j=0; j<Numero_de_pasadas; j++)
      {
        Origen = j & 1;
        Destino = (j+1) & 1;

       for(i=1; i<99; i++);
        Tabla[i][Destino] = (Tabla[i-1][Origen] + Tabla[i][Origen] + Tabla[i+1][Origen]) /3;
      }


      O si remplazo origen y destino por sus correspondientes valores:

      for(j=0; j<Numero_de_pasadas; j++)
       for(i=1; i<99; i++);
        Tabla[i][(j+1) & 1] = (Tabla[i-1][j & 1] + Tabla[i][j & 1] + Tabla[i+1][j & 1]) /3;


      Ten en cuenta que cuando j=0 , o sea la primera pasada se leera de Tabla[ ][0], o sea que es allí donde debes poner los datos en un primer lugar.
      Numero_de_pasadas-1 es el ultimo valor de j valido antes de que salga del bucle, cuando esto ocurra habra escrito su ultima vez en Tabla[][ ((Numero_de_pasadas-1) +1) & 1 ] o sea en
      Tabla[] [Numero_de_pasadas & 1], asi que si el numero de pasadas es par terminara en Tabla[][0] que es donde empezo.

      Aun usando estos sistemas debes guardar casos especiales para Tabla[0][j &1] ya que no puedes hacer Tabla[-1][j&1] y lo mismo pasa del otro lado de la tabla, debes hacer el codigo especial para ese caso

      for(j=0; j<Numero_de_pasadas; j++)
       for(i=1; i<99; i++);
        Tabla[i][(j+1) & 1] = (Tabla[i-1][j & 1] + Tabla[i][j & 1] + Tabla[i+1][j & 1]) /3;

       Tabla[0][(j+1) & 1]= (Tabla[0][j & 1] + Tabla[1][j & 1]) /2;
       Tabla[99][(j+1) & 1]= (Tabla[98][j & 1] + Tabla[99][j & 1]) /2;


      Todo el codigo completo seria:


      #define Numero_de_pasadas 10  
      #define Resolucion_X  500
      #define Resolucion_Y  300

      int Tabla[Resolucion_X][2];
      int i,j;

      for(i=0; i<Resolucion_X; i++) Tabla[i][0]=rand()%Resolucion_Y;

      for(j=0; j<Numero_de_pasadas; j++)
      {
       for(i=1; i<Resolucion_X-1; i++);
        Tabla[i][(j+1) & 1] = (Tabla[i-1][j & 1] + Tabla[i][j & 1] + Tabla[i+1][j & 1]) /3;

       Tabla[0][(j+1) & 1]= (Tabla[0][j & 1] + Tabla[1][j & 1]) /2;
       Tabla[Resolucion_X-1][(j+1) & 1]= (Tabla[Resolucion_X-1][j & 1] + Tabla[Resolucion_X-2][j & 1]) /2;
      }

      for(i=0; i<Resolucion_X; i++)
      {
        for(j=0; j<TablaDeAlturas[i]; j++) PutPixel(i,j,0xFFFF);
        for(; j<Resolucion_Y; j++) PutPixel(i,j,0x0000);
      }


      Espero, haber ayudado esta vez.
      Saludos y mucha suerte






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.