Skip to content

Instantly share code, notes, and snippets.

@manse
Created November 15, 2017 03:21
Show Gist options
  • Save manse/ca96ffeb77e8a47d798a2d9632e019be to your computer and use it in GitHub Desktop.
Save manse/ca96ffeb77e8a47d798a2d9632e019be to your computer and use it in GitHub Desktop.
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: LatticedLiquid2.java
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.MemoryImageSource;
import java.util.Arrays;
public class LatticedLiquid2 extends Applet
implements Runnable, MouseListener, MouseMotionListener, KeyListener
{
public LatticedLiquid2()
{
airDensity = 0.001D;
minMass = 9.9999999999999995E-07D;
equalizerBias = 9.9999999999999995E-07D;
gravityX = 0.0D;
gravityY = 0.5D;
tension = 0.80000000000000004D;
}
public synchronized void init()
{
try
{
scale = Integer.parseInt(getParameter("scale"));
}
catch(RuntimeException runtimeexception) { }
xbits = Math.max(4, (int)Math.round(Math.log(getWidth()) / Math.log(2D)) - scale);
ybits = Math.max(4, (int)Math.round(Math.log(getHeight()) / Math.log(2D)) - scale);
xmax = (1 << xbits) - 1;
ymax = (1 << ybits) - 1;
shift = xbits;
size = 1 << xbits + ybits;
air = new double[size + 1];
liq = new double[size + 1];
room = new double[size + 1];
velocityX = new double[size + 1];
velocityY = new double[size + 1];
minVelocityX = new double[size + 1];
minVelocityY = new double[size + 1];
maxVelocityX = new double[size + 1];
maxVelocityY = new double[size + 1];
momentumX = new double[size + 1];
momentumY = new double[size + 1];
airBuffer = new double[size + 1];
liqBuffer = new double[size + 1];
airFluxX = new double[size + 1];
airFluxY = new double[size + 1];
liqFluxX = new double[size + 1];
liqFluxY = new double[size + 1];
pressure = new Grid(xbits, ybits);
equalizer = new Grid(xbits, ybits);
pixels = new int[size + 1];
imageSource = new MemoryImageSource(1 << xbits, 1 << ybits, pixels, 0, 1 << xbits);
imageSource.setAnimated(true);
image = getToolkit().createImage(imageSource);
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
}
public synchronized void start()
{
reset(1);
thread = new Thread(this);
thread.setDaemon(true);
thread.start();
}
private synchronized void reset(int type)
{
Arrays.fill(air, 0.0D);
Arrays.fill(liq, 0.0D);
Arrays.fill(momentumX, 0.0D);
Arrays.fill(momentumY, 0.0D);
Arrays.fill(velocityX, 0.0D);
Arrays.fill(velocityY, 0.0D);
Arrays.fill(minVelocityX, -xmax);
Arrays.fill(maxVelocityX, xmax);
Arrays.fill(minVelocityY, -ymax);
Arrays.fill(maxVelocityY, ymax);
switch(type)
{
case 1: // '\001'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
if(x != 0 && x != xmax && y != 0 && y != ymax)
if(x < xmax / 2)
liq[i] = 1.0D;
else
air[i] = 1.0D;
minVelocityX[i] = Math.min(0, 1 - x);
maxVelocityX[i] = Math.max(0, xmax - 1 - x);
minVelocityY[i] = Math.min(0, 1 - y);
maxVelocityY[i] = Math.max(0, ymax - 1 - y);
x++;
i++;
}
}
break;
}
case 2: // '\002'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
if(y != 0 && y != ymax)
if(y > ymax / 2)
liq[i] = 1.0D;
else
air[i] = 1.0D;
minVelocityX[i] = -xmax;
maxVelocityX[i] = xmax;
minVelocityY[i] = Math.min(0, 1 - y);
maxVelocityY[i] = Math.max(0, ymax - 1 - y);
x++;
i++;
}
}
break;
}
case 3: // '\003'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
if(y != 0 && y != ymax)
if(y < ymax / 2)
liq[i] = 1.0D;
else
air[i] = 1.0D;
minVelocityX[i] = -xmax;
maxVelocityX[i] = xmax;
minVelocityY[i] = Math.min(0, 1 - y);
maxVelocityY[i] = Math.max(0, ymax - 1 - y);
x++;
i++;
}
}
break;
}
case 4: // '\004'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
if(x != 0 && x != xmax && y != 0 && y != ymax && (x <= xmax / 4 || x >= (xmax * 3) / 4 || y <= ymax / 4 || y >= (ymax * 3) / 4))
if(y > ymax / 2)
liq[i] = 1.0D;
else
air[i] = 1.0D;
minVelocityX[i] = Math.min(0, 1 - x);
maxVelocityX[i] = Math.max(0, xmax - 1 - x);
minVelocityY[i] = Math.min(0, 1 - y);
maxVelocityY[i] = Math.max(0, ymax - 1 - y);
x++;
i++;
}
}
break;
}
case 5: // '\005'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
if(x != xmax / 3 && y != ymax / 3)
if(y > ymax / 2)
liq[i] = 1.0D;
else
air[i] = 1.0D;
x++;
i++;
}
}
break;
}
case 6: // '\006'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double w = Math.max(0.0D, Math.min((double)(Math.min(xmax, ymax) / 2 - 2) - Math.hypot(x - xmax / 2, y - ymax / 2), 1.0D));
if(y > ymax / 2)
liq[i] = w;
else
air[i] = w;
x++;
i++;
}
}
break;
}
default:
{
return;
}
}
for(int i = 0; i < size; i++)
room[i] = air[i] + liq[i];
}
public void run()
{
while(!Thread.interrupted())
{
updatePhase();
updateImage();
try
{
Thread.sleep(20L);
continue;
}
catch(InterruptedException e) { }
break;
}
}
private synchronized void updatePhase()
{
applyForce();
applyAdvection();
applyEqualization();
}
private void applyForce()
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int j = x - 1 & xmax | y << shift;
double r = Math.min(room[i], room[j]);
double a = air[i] + air[j];
double b = liq[i] + liq[j];
double m = airDensity * a + b;
double p = 2D * momentumX[i] + m * gravityX;
m = Math.max(m, minMass);
velocityX[i] = (r * p) / m;
pressure.linkX[i] = r / m;
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int j = x | (y - 1 & ymax) << shift;
double r = Math.min(room[i], room[j]);
double a = air[i] + air[j];
double b = liq[i] + liq[j];
double m = airDensity * a + b;
double p = 2D * momentumY[i] + m * gravityY;
m = Math.max(m, minMass);
velocityY[i] = (r * p) / m;
pressure.linkY[i] = r / m;
x++;
i++;
}
}
if(lastMousePoint != null)
{
cursorVelocityX += (2D * (((double)lastMousePoint.x - cursorX) / 5D - cursorVelocityX)) / 5D;
cursorVelocityY += (2D * (((double)lastMousePoint.y - cursorY) / 5D - cursorVelocityY)) / 5D;
double scaledCursorX = (cursorX / (double)getWidth()) * (double)xmax;
double scaledCursorY = (cursorY / (double)getHeight()) * (double)ymax;
double scaledVelocityX = (cursorVelocityX / (double)getWidth()) * (double)xmax;
double scaledVelocityY = (cursorVelocityY / (double)getHeight()) * (double)ymax;
applyMouse(scaledCursorX, scaledCursorY, scaledVelocityX, scaledVelocityY, 10D);
cursorX += cursorVelocityX;
cursorY += cursorVelocityY;
}
scaledCursorX = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
pressure.source[scaledCursorX] = ((velocityX[scaledCursorX] - velocityX[x + 1 & xmax | y << shift]) + velocityY[scaledCursorX]) - velocityY[x | (y + 1 & ymax) << shift];
x++;
scaledCursorX++;
}
}
pressure.solve(10);
scaledCursorX = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int j = x - 1 & xmax | y << shift;
double p = pressure.value[j] - pressure.value[scaledCursorX];
velocityX[scaledCursorX] += pressure.linkX[scaledCursorX] * p;
x++;
scaledCursorX++;
}
}
scaledCursorX = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int j = x | (y - 1 & ymax) << shift;
double p = pressure.value[j] - pressure.value[scaledCursorX];
velocityY[scaledCursorX] += pressure.linkY[scaledCursorX] * p;
x++;
scaledCursorX++;
}
}
}
private void applyAdvection()
{
Arrays.fill(airBuffer, 0.0D);
Arrays.fill(liqBuffer, 0.0D);
Arrays.fill(momentumX, 0.0D);
Arrays.fill(momentumY, 0.0D);
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double vx0 = velocityX[i];
double vx1 = velocityX[x + 1 & xmax | y << shift];
double vy0 = velocityY[i];
double vy1 = velocityY[x | (y + 1 & ymax) << shift];
double gx = tension * (liq[x - 1 & xmax | y << shift] - liq[x + 1 & xmax | y << shift]);
double gy = tension * (liq[x | (y - 1 & ymax) << shift] - liq[x | (y + 1 & ymax) << shift]);
double vx = Math.max(minVelocityX[i], Math.min(0.5D * (vx0 + vx1 + gx), maxVelocityX[i]));
double vy = Math.max(minVelocityY[i], Math.min(0.5D * (vy0 + vy1 + gy), maxVelocityY[i]));
double dx = (double)(x + xmax + 1) + vx;
double dy = (double)(y + ymax + 1) + vy;
int ix = (int)dx;
int iy = (int)dy;
dx -= ix;
dy -= iy;
double w00 = (1.0D - dx) * (1.0D - dy);
double w01 = (1.0D - dx) * dy;
double w10 = dx * (1.0D - dy);
double w11 = dx * dy;
int x0 = ix & xmax;
int y0 = (iy & ymax) << shift;
int x1 = ix + 1 & xmax;
int y1 = (iy + 1 & ymax) << shift;
int x2 = ix + 2 & xmax;
int y2 = (iy + 2 & ymax) << shift;
double a = air[i];
double m = 0.5D * airDensity * a;
airBuffer[x0 | y0] += a * w00;
airBuffer[x0 | y1] += a * w01;
airBuffer[x1 | y0] += a * w10;
airBuffer[x1 | y1] += a * w11;
momentumX[x0 | y0] += m * vx0 * w00;
momentumX[x1 | y0] += m * vx0 * w10 + m * vx1 * w00;
momentumX[x2 | y0] += m * vx1 * w10;
momentumX[x0 | y1] += m * vx0 * w01;
momentumX[x1 | y1] += m * vx0 * w11 + m * vx1 * w01;
momentumX[x2 | y1] += m * vx1 * w11;
momentumY[x0 | y0] += m * vy0 * w00;
momentumY[x0 | y1] += m * vy0 * w01 + m * vy1 * w00;
momentumY[x0 | y2] += m * vy1 * w01;
momentumY[x1 | y0] += m * vy0 * w10;
momentumY[x1 | y1] += m * vy0 * w11 + m * vy1 * w10;
momentumY[x1 | y2] += m * vy1 * w11;
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double vx0 = velocityX[i];
double vx1 = velocityX[x + 1 & xmax | y << shift];
double vy0 = velocityY[i];
double vy1 = velocityY[x | (y + 1 & ymax) << shift];
double gx = tension * (air[x - 1 & xmax | y << shift] - air[x + 1 & xmax | y << shift]);
double gy = tension * (air[x | (y - 1 & ymax) << shift] - air[x | (y + 1 & ymax) << shift]);
double vx = Math.max(minVelocityX[i], Math.min(0.5D * (vx0 + vx1 + gx), maxVelocityX[i]));
double vy = Math.max(minVelocityY[i], Math.min(0.5D * (vy0 + vy1 + gy), maxVelocityY[i]));
double dx = (double)(x + xmax + 1) + vx;
double dy = (double)(y + ymax + 1) + vy;
int ix = (int)dx;
int iy = (int)dy;
dx -= ix;
dy -= iy;
double w00 = (1.0D - dx) * (1.0D - dy);
double w01 = (1.0D - dx) * dy;
double w10 = dx * (1.0D - dy);
double w11 = dx * dy;
int x0 = ix & xmax;
int y0 = (iy & ymax) << shift;
int x1 = ix + 1 & xmax;
int y1 = (iy + 1 & ymax) << shift;
int x2 = ix + 2 & xmax;
int y2 = (iy + 2 & ymax) << shift;
double b = liq[i];
double m = 0.5D * b;
liqBuffer[x0 | y0] += b * w00;
liqBuffer[x0 | y1] += b * w01;
liqBuffer[x1 | y0] += b * w10;
liqBuffer[x1 | y1] += b * w11;
momentumX[x0 | y0] += m * vx0 * w00;
momentumX[x1 | y0] += m * vx0 * w10 + m * vx1 * w00;
momentumX[x2 | y0] += m * vx1 * w10;
momentumX[x0 | y1] += m * vx0 * w01;
momentumX[x1 | y1] += m * vx0 * w11 + m * vx1 * w01;
momentumX[x2 | y1] += m * vx1 * w11;
momentumY[x0 | y0] += m * vy0 * w00;
momentumY[x0 | y1] += m * vy0 * w01 + m * vy1 * w00;
momentumY[x0 | y2] += m * vy1 * w01;
momentumY[x1 | y0] += m * vy0 * w10;
momentumY[x1 | y1] += m * vy0 * w11 + m * vy1 * w10;
momentumY[x1 | y2] += m * vy1 * w11;
x++;
i++;
}
}
System.arraycopy(airBuffer, 0, air, 0, size);
System.arraycopy(liqBuffer, 0, liq, 0, size);
}
private void applyEqualization()
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int j = x - 1 & xmax | y << shift;
double r = Math.min(room[i], room[j]);
double a = air[i] + air[j];
double b = liq[i] + liq[j];
double m = Math.max(airDensity * a + b, minMass);
equalizer.linkX[i] = (r * (a + b)) / m + 2D * equalizerBias;
airFluxX[i] = (r * a) / m + equalizerBias;
liqFluxX[i] = (r * b) / m + equalizerBias;
velocityX[i] = (2D * r * momentumX[i]) / m;
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int j = x | (y - 1 & ymax) << shift;
double r = Math.min(room[i], room[j]);
double a = air[i] + air[j];
double b = liq[i] + liq[j];
double m = Math.max(airDensity * a + b, minMass);
equalizer.linkY[i] = (r * (a + b)) / m + 2D * equalizerBias;
airFluxY[i] = (r * a) / m + equalizerBias;
liqFluxY[i] = (r * b) / m + equalizerBias;
velocityY[i] = (2D * r * momentumY[i]) / m;
x++;
i++;
}
}
for(i = 0; i < size; i++)
equalizer.source[i] = (air[i] + liq[i]) - room[i];
equalizer.solve(5);
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int j = x - 1 & xmax | y << shift;
double p = equalizer.value[j] - equalizer.value[i];
airFluxX[i] *= p;
liqFluxX[i] *= p;
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int j = x | (y - 1 & ymax) << shift;
double p = equalizer.value[j] - equalizer.value[i];
airFluxY[i] *= p;
liqFluxY[i] *= p;
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int ix = x + 1 & xmax | y << shift;
int iy = x | (y + 1 & ymax) << shift;
airBuffer[i] = Math.min(1.0D, air[i] / ((((9.9999999999999995E-07D + Math.max(0.0D, airFluxX[ix])) - Math.min(0.0D, airFluxX[i])) + Math.max(0.0D, airFluxY[iy])) - Math.min(0.0D, airFluxY[i])));
liqBuffer[i] = Math.min(1.0D, liq[i] / ((((9.9999999999999995E-07D + Math.max(0.0D, liqFluxX[ix])) - Math.min(0.0D, liqFluxX[i])) + Math.max(0.0D, liqFluxY[iy])) - Math.min(0.0D, liqFluxY[i])));
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int ix = x - 1 & xmax | y << shift;
int iy = x | (y - 1 & ymax) << shift;
double ax = airFluxX[i];
double ay = airFluxY[i];
double bx = liqFluxX[i];
double by = liqFluxY[i];
airFluxX[i] = ax * airBuffer[ax <= 0.0D ? i : ix];
airFluxY[i] = ay * airBuffer[ay <= 0.0D ? i : iy];
liqFluxX[i] = bx * liqBuffer[bx <= 0.0D ? i : ix];
liqFluxY[i] = by * liqBuffer[by <= 0.0D ? i : iy];
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double a = airFluxX[i];
double b = liqFluxX[i];
double m = 0.5D * (airDensity * a + b);
int ix0 = x - 1 & xmax | y << shift;
int ix1 = x + 1 & xmax | y << shift;
int iy1 = x | (y + 1 & ymax) << shift;
int ixy = x - 1 & xmax | (y + 1 & ymax) << shift;
double px0 = m * velocityX[m <= 0.0D ? i : ix0];
double px1 = m * velocityX[m <= 0.0D ? ix1 : i];
double py0 = m * velocityY[m <= 0.0D ? i : ix0];
double py1 = m * velocityY[m <= 0.0D ? iy1 : ixy];
momentumX[ix0] -= px0;
momentumX[i] += px0 - px1;
momentumX[ix1] += px1;
momentumY[ix0] -= py0;
momentumY[i] += py0;
momentumY[ixy] -= py1;
momentumY[iy1] += py1;
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double a = airFluxY[i];
double b = liqFluxY[i];
double m = 0.5D * (airDensity * a + b);
int ix1 = x + 1 & xmax | y << shift;
int iy0 = x | (y - 1 & ymax) << shift;
int iy1 = x | (y + 1 & ymax) << shift;
int ixy = x + 1 & xmax | (y - 1 & ymax) << shift;
double px0 = m * velocityX[m <= 0.0D ? i : iy0];
double px1 = m * velocityX[m <= 0.0D ? ix1 : ixy];
double py0 = m * velocityY[m <= 0.0D ? i : iy0];
double py1 = m * velocityY[m <= 0.0D ? iy1 : i];
momentumX[iy0] -= px0;
momentumX[i] += px0;
momentumX[ixy] -= px1;
momentumX[ix1] += px1;
momentumY[iy0] -= py0;
momentumY[i] += py0 - py1;
momentumY[iy1] += py1;
x++;
i++;
}
}
i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
int ix = x + 1 & xmax | y << shift;
int iy = x | (y + 1 & ymax) << shift;
air[i] += ((airFluxX[i] - airFluxX[ix]) + airFluxY[i]) - airFluxY[iy];
liq[i] += ((liqFluxX[i] - liqFluxX[ix]) + liqFluxY[i]) - liqFluxY[iy];
x++;
i++;
}
}
}
public void applyMouse(double ox, double oy, double vx, double vy, double r)
{
double v2 = vx * vx + vy * vy;
double r2 = r * r;
for(int y = 0; y < ymax; y++)
{
for(int x = 0; x < xmax; x++)
{
double dx = (double)x - ox;
double dy = (double)y - oy;
double d2 = dx * dx + dy * dy;
double dv = dx * vx + dy * vy;
if(dv > 0.0D)
if(dv < v2)
d2 -= (dv * dv) / v2;
else
d2 += v2 - 2D * dv;
if(d2 < r2)
{
double w = d2 / r2;
int i0 = x | y << shift;
int ix = x + 1 & xmax | y << shift;
int iy = x | (y + 1 & ymax) << shift;
velocityX[i0] = w * velocityX[i0] + (1.0D - w) * vx;
velocityX[ix] = w * velocityX[ix] + (1.0D - w) * vx;
velocityY[i0] = w * velocityY[i0] + (1.0D - w) * vy;
velocityY[iy] = w * velocityY[iy] + (1.0D - w) * vy;
}
}
}
}
private synchronized void updateImage()
{
value = 0.0D;
switch(imageType)
{
case 118: // 'v'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double vx = 0.5D * (velocityX[i] + velocityX[x + 1 & xmax | y << shift]);
double vy = 0.5D * (velocityY[i] + velocityY[x | (y + 1 & ymax) << shift]);
pixels[i] = makePixel(vx, 0.86599999999999999D * vy - vx / 2D, -0.86599999999999999D * vy - vx / 2D);
x++;
i++;
}
}
break;
}
case 117: // 'u'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double px = 0.5D * (momentumX[i] + momentumX[x + 1 & xmax | y << shift]);
double py = 0.5D * (momentumY[i] + momentumY[x | (y + 1 & ymax) << shift]);
pixels[i] = makePixel(px, 0.86599999999999999D * py - px / 2D, -0.86599999999999999D * py - px / 2D);
x++;
i++;
}
}
break;
}
case 119: // 'w'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double w = ((velocityY[x + 1 & xmax | y << shift] - velocityY[x - 1 & xmax | y << shift]) + velocityX[x | (y + 1 & ymax) << shift]) - velocityX[x | (y - 1 & ymax) << shift];
pixels[i] = makePixel(w, -w, 0.0D);
value += w;
x++;
i++;
}
}
break;
}
case 115: // 's'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double s = ((velocityX[i] - velocityX[x + 1 & xmax | y << shift]) + velocityY[i]) - velocityY[x | (y + 1 & ymax) << shift];
pixels[i] = makePixel(s, -s, 0.0D);
value += s;
x++;
i++;
}
}
break;
}
case 120: // 'x'
{
for(int i = 0; i < size; i++)
{
double v = velocityX[i];
pixels[i] = makePixel(v, -v, 0.0D);
value += momentumX[i];
}
break;
}
case 121: // 'y'
{
for(int i = 0; i < size; i++)
{
double v = velocityY[i];
pixels[i] = makePixel(v, -v, 0.0D);
value += momentumY[i];
}
break;
}
case 112: // 'p'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double p = pressure.value[i];
pixels[i] = makePixel(p, -p, 0.0D);
value += p;
x++;
i++;
}
}
break;
}
case 101: // 'e'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double p = equalizer.value[i];
pixels[i] = makePixel(p, -p, 0.0D);
value += p;
x++;
i++;
}
}
break;
}
case 113: // 'q'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double p = equalizer.source[i];
pixels[i] = makePixel(p, -p, 0.0D);
value += p;
x++;
i++;
}
}
break;
}
case 97: // 'a'
{
for(int i = 0; i < size; i++)
{
double a = air[i];
pixels[i] = makePixel(a, a, a);
value += a;
}
break;
}
case 98: // 'b'
{
for(int i = 0; i < size; i++)
{
double b = liq[i];
pixels[i] = makePixel(b, b, b);
value += b;
}
break;
}
case 99: // 'c'
{
for(int i = 0; i < size; i++)
{
double r = room[i];
double a = air[i];
double b = liq[i];
pixels[i] = makePixel(b, a, 1.0D - r);
value += b + a;
}
break;
}
case 109: // 'm'
{
for(int i = 0; i < size; i++)
{
double a = air[i];
double b = liq[i];
double m = airDensity * a + b;
pixels[i] = makePixel(m / 2D, m / 2D, m / 2D);
value += m;
}
break;
}
case 104: // 'h'
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double a = Math.min(air[i], 1.0D);
double b = Math.min(liq[i], 1.0D);
double g = Math.hypot(liq[x + 1 & xmax | y << shift] - liq[x - 1 & xmax | y << shift], liq[x | (y + 1 & ymax) << shift] - liq[x | (y - 1 & ymax) << shift]);
double s = Math.max(0.0D, Math.min(2D * a * b - 0.29999999999999999D * g, 1.0D));
double h = (double)y / (double)ymax;
pixels[i] = makePixel((1.0D - s) * ((1.0D - b) * ((1.0D - h) * 0.90000000000000002D + h * 0.29999999999999999D) + b * ((1.0D - h) * 0.20000000000000001D + h * 0.10000000000000001D)) + s, (1.0D - s) * ((1.0D - b) * ((1.0D - h) * 0.80000000000000004D + h * 0.29999999999999999D) + b * ((1.0D - h) * 0.40000000000000002D + h * 0.20000000000000001D)) + s, (1.0D - s) * ((1.0D - b) * ((1.0D - h) * 0.69999999999999996D + h * 0.29999999999999999D) + b * ((1.0D - h) * 0.69999999999999996D + h * 0.40000000000000002D)) + s);
x++;
i++;
}
}
break;
}
case 100: // 'd'
case 102: // 'f'
case 103: // 'g'
case 105: // 'i'
case 106: // 'j'
case 107: // 'k'
case 108: // 'l'
case 110: // 'n'
case 111: // 'o'
case 114: // 'r'
case 116: // 't'
default:
{
int i = 0;
for(int y = 0; y <= ymax; y++)
{
for(int x = 0; x <= xmax;)
{
double gx = liq[x + 1 & xmax | y << shift] - liq[x - 1 & xmax | y << shift];
double gy = liq[x | (y + 1 & ymax) << shift] - liq[x | (y - 1 & ymax) << shift];
double g2 = gx * gx + gy * gy;
double lx = x - xmax / 2;
double ly = y + ymax;
double l2 = lx * lx + ly * ly;
double gl = gx * lx + gy * ly;
double r = Math.min(g2, 1.0D);
double d = Math.min(2D * air[i] * liq[i], 1.0D);
double s = (0.5D * gl * gl) / ((g2 + 1.0D) * l2);
pixels[i] = makePixel((1.0D - d) * ((1.0D - r) * 0.5D + r * 0.29999999999999999D) + d + s, (1.0D - d) * ((1.0D - r) * 0.80000000000000004D + r * 0.59999999999999998D) + d + s, (1.0D - d) * ((1.0D - r) * 0.80000000000000004D + r * 0.59999999999999998D) + d + s);
x++;
i++;
}
}
break;
}
}
imageSource.newPixels();
repaint();
}
public synchronized void stop()
{
thread.interrupt();
}
public synchronized void destroy()
{
removeMouseListener(this);
removeMouseMotionListener(this);
removeKeyListener(this);
}
public void mouseClicked(MouseEvent mouseevent)
{
}
public void mouseEntered(MouseEvent mouseevent)
{
}
public void mouseExited(MouseEvent mouseevent)
{
}
public synchronized void mousePressed(MouseEvent e)
{
lastMousePoint = e.getPoint();
cursorX = lastMousePoint.x;
cursorY = lastMousePoint.y;
cursorVelocityX = 0.0D;
cursorVelocityY = 0.0D;
}
public synchronized void mouseReleased(MouseEvent e)
{
lastMousePoint = null;
}
public synchronized void mouseDragged(MouseEvent e)
{
lastMousePoint = e.getPoint();
}
public void mouseMoved(MouseEvent mouseevent)
{
}
public void keyPressed(KeyEvent keyevent)
{
}
public void keyReleased(KeyEvent keyevent)
{
}
public void keyTyped(KeyEvent e)
{
char type = e.getKeyChar();
if(type == ' ')
synchronized(this)
{
Arrays.fill(velocityX, 0.0D);
Arrays.fill(velocityY, 0.0D);
Arrays.fill(momentumX, 0.0D);
Arrays.fill(momentumY, 0.0D);
}
else
if(type == imageType)
imageType = '\0';
else
if('0' <= type && type <= '9')
reset(type - 48);
else
imageType = type;
}
public void update(Graphics g)
{
paint(g);
}
public synchronized void paint(Graphics g)
{
if(scale > 0)
{
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
} else
{
g.drawImage(image, 0, 0, this);
}
if(value != 0.0D)
{
g.setColor(Color.white);
g.drawString(String.valueOf(value), 0, getHeight());
}
}
private static int makePixel(double f1, double f2, double f3)
{
int c1 = Math.max(0, Math.min((int)(255D * f1), 255));
int c2 = Math.max(0, Math.min((int)(255D * f2), 255));
int c3 = Math.max(0, Math.min((int)(255D * f3), 255));
return 0xff000000 | c1 << 16 | c2 << 8 | c3;
}
static final long serialVersionUID = 0L;
private int scale;
private int xbits;
private int ybits;
private int xmax;
private int ymax;
private int shift;
private int size;
private double air[];
private double liq[];
private double room[];
private double velocityX[];
private double velocityY[];
private double minVelocityX[];
private double minVelocityY[];
private double maxVelocityX[];
private double maxVelocityY[];
private double momentumX[];
private double momentumY[];
private double airBuffer[];
private double liqBuffer[];
private double airFluxX[];
private double airFluxY[];
private double liqFluxX[];
private double liqFluxY[];
private Grid pressure;
private Grid equalizer;
private double airDensity;
private double minMass;
private double equalizerBias;
private double gravityX;
private double gravityY;
private double tension;
private char imageType;
private int pixels[];
private MemoryImageSource imageSource;
private Image image;
private double value;
private Point lastMousePoint;
private double cursorX;
private double cursorY;
private double cursorVelocityX;
private double cursorVelocityY;
private Thread thread;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment