Nombre: Metaballs 2D
Descripción:
Consiste en un pequeño applet que muestra una animación de dos metaballs (bloobs) moviéndose. Para la generación de los metaballs se utiliza la formula de newtom de la atracción entre dos cuerpos.
URL: http://www.mygnet.net/codigos/java/analisisnumericos/metaballs_2d.902
Código Fuente:
/* *
* <applet code=bloobs.class width=850 height=650>
* <param name="width" value="600">
* <param name="height" value="500">
* </applet>
*
* */
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class bloobs extends Applet implements Runnable
{
/*Defino la masa para el boob 1 y el 2 y para cada uno de los pixels*/
final static int MASA1=2000;
final static int MASA2=1000;
final static int MASA_PARTICULAS = 255;
/*como en la formula de newton la parte de arriba es masa del primero por masa del segundo
* y todos los pixels tienen la misma masa, este valor siempre será el mismo, con lo cual
* y alo calculo como una constante*/
final static int CONSTANTE1 = MASA_PARTICULAS * MASA1;
final static int CONSTANTE2 = MASA_PARTICULAS * MASA2;
/*variables para especificar el sentido de la animación
* y que los bloobs no se salgan de la pantalla*/
int sentidoX= 1,sentidoY=-1;
/*posiciones de los dos bloobs*/
int X1=50, X2=150;
int Y1=125,Y2=200;
//thread que realizará el calculo de la imagen y la animación
Thread t;
//buffer donde se almacenrá la imagen calculada
int buffer[];
//ancho y alto de la imagen
int width,height;
//Objetos para la construcción de la imagen final a partir del buffer
Image image;
MemoryImageSource memory;
public void init()
{
String datos;
t=new Thread(this,"Pepito");
datos=getParameter("width");
width=Integer.parseInt(datos);
datos=getParameter("height");
height=Integer.parseInt(datos);
buffer=new int[height*width];
/*memory = new MemoryImageSource(width,height,buffer,0,width);
memory.setAnimated(true);
memory.setFullBufferUpdates(true);*/
}
public void start()
{
t.start();
}
public void run()
{
while(true)
{
blobs();
//construyo la imagen a partir del buffer que se acaba de calcular
image=createImage(new MemoryImageSource(width,height,buffer,0,width));
//pinto la imagen en pantalla
repaint();
//modifico los valores de X del primer bloob y de Y del segundo
//para el próximo frame
X1+= sentidoX;
Y2+= sentidoY;
if(X1>=width-50) sentidoX = -1;
if(X1<= 50) sentidoX = 1;
if(Y2>=250) sentidoY = -1;
if(Y2<=25) sentidoY = 1;
try
{
//establezco una pausa de 10 milisegundos para que no
//consuma tanto de procesador
Thread.sleep(10);
}
catch(InterruptedException e)
{
System.err.println("Interrupted Exception!!!");
}
}
}
public void update(Graphics g)
{
paint(g);
}
public void paint(Graphics g)
{
g.drawImage(image,0,0,this);
}
/*calcula los bloobs conla fórmula de newtom sobre la atracción
* entre dos cuerpos, según la cual:
*
* fuerza = masa_del_primero * masa_del_segundo / distantcia que los separa al cuadrado
*
* Para calcular la distancia entre los dos cuerpos (pixel actual y la posición del bloob para el que
* quiero calcular la fuerza de atracción) utilizo la fórmula matemática de distancia entre puntos,
* segunla cual la distancia es igual a la suma de los cuadrados de la diferencias de sus coordenadas,
* es decir:
*
* distancia = (x_primer_punto - x_segundo_punto * x_primer_punto - x_segundo_punto) +
* (y_primer_punto - y_segundo_punto * y_primer_punto - y_segundo_punto)
* */
void blobs()
{
int x=0,y=0,i=0;
int d=0,a=0,b=0,/*auxr=0xFF,auxg=0xFF,auxb=0xFF,*/fr=0,fg=0,fb=0;
int a2=0,b2=0,d2 = 0;
for(y=0;y<height;y++)
{
/*direrencia de las coordenadas y*/
a=Y1-y; a2=Y2-y;
for(x=0;x<width;x++)
{
/*diferencia de las coordenadas x*/
b=X1-x; b2 = X2-x;
/*calculo de la distancia*/
d=a*a+b*b; d2 = a2*a2+b2*b2;
/*para evitar divisiones por cero*/
if(d2 == 0) d2 = 1;
if(d == 0) d = 1;
/*el valor total para el pixel actual es igual a la suma de los valores respecto a ambos bloobs*/
int value = CONSTANTE1 / d + CONSTANTE2 / d2;
/*asigna los valores a las componentes r,g,b del pixel en base al valor anterior*/
fr=value << 1;
fg=value >> 1;
fb=value << 1;
if(fr>0xFF) fr=0xFF;
if(fg>0xFF) fg=0xFF;
if(fb>0xFF) fb=0xFF;
buffer[i]=(255<<24)|(fr<<16)|(fg<<8)|fb;
i++;
}
}
}
}