|
|
9e0c72 |
|
|
|
9e0c72 |
#include <math.h></math.h>
|
|
|
9e0c72 |
#include <stdlib.h></stdlib.h>
|
|
|
9e0c72 |
#include <helianthus.h></helianthus.h>
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
#define SIZE 100
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
double matrix[3][2] = {
|
|
|
9e0c72 |
{ 5, 2 },
|
|
|
9e0c72 |
{ 5, -2 },
|
|
|
9e0c72 |
{ 0, -5 } };
|
|
|
9e0c72 |
|
|
|
9e0c72 |
double invMatrix[2][2] = {
|
|
|
9e0c72 |
{ 0.1 , 0.1 },
|
|
|
9e0c72 |
{ 0.25, -0.25 } };
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
double grid[2][SIZE][SIZE];
|
|
|
9e0c72 |
int gridId = 0;
|
|
|
9e0c72 |
double simTm;
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
double calcX(double x, double y, double z)
|
|
|
9e0c72 |
{ return matrix[0][0]*x + matrix[1][0]*y + matrix[2][0]*z; }
|
|
|
9e0c72 |
double calcY(double x, double y, double z)
|
|
|
9e0c72 |
{ return matrix[0][1]*x + matrix[1][1]*y + matrix[2][1]*z; }
|
|
|
9e0c72 |
|
|
|
9e0c72 |
double calcBackX(double sx, double sy)
|
|
|
9e0c72 |
{ return invMatrix[0][0]*sx + invMatrix[1][0]*sy; }
|
|
|
9e0c72 |
double calcBackY(double sx, double sy)
|
|
|
9e0c72 |
{ return invMatrix[0][1]*sx + invMatrix[1][1]*sy; }
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
void drawBox(double x, double y, double z, double dx, double dy, double dz, unsigned int color) {
|
|
|
9e0c72 |
saveState();
|
|
|
9e0c72 |
double ch = colorGetHue(color);
|
|
|
9e0c72 |
double cs = colorGetSaturation(color);
|
|
|
9e0c72 |
double cv = colorGetValue(color);
|
|
|
9e0c72 |
|
|
|
9e0c72 |
noStroke();
|
|
|
9e0c72 |
|
|
|
9e0c72 |
fill(colorByHSV(ch, cs, cv*0.6));
|
|
|
9e0c72 |
moveTo( calcX(x, y, z),
|
|
|
9e0c72 |
calcY(x, y, z) );
|
|
|
9e0c72 |
lineTo( calcX(x+dx, y, z),
|
|
|
9e0c72 |
calcY(x+dx, y, z) );
|
|
|
9e0c72 |
lineTo( calcX(x+dx, y, z+dz),
|
|
|
9e0c72 |
calcY(x+dx, y, z+dz) );
|
|
|
9e0c72 |
lineTo( calcX(x, y, z+dz),
|
|
|
9e0c72 |
calcY(x, y, z+dz) );
|
|
|
9e0c72 |
closePath();
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
fill(colorByHSV(ch, cs, cv*0.8));
|
|
|
9e0c72 |
moveTo( calcX(x+dx, y, z),
|
|
|
9e0c72 |
calcY(x+dx, y, z) );
|
|
|
9e0c72 |
lineTo( calcX(x+dx, y+dy, z),
|
|
|
9e0c72 |
calcY(x+dx, y+dy, z) );
|
|
|
9e0c72 |
lineTo( calcX(x+dx, y+dy, z+dz),
|
|
|
9e0c72 |
calcY(x+dx, y+dy, z+dz) );
|
|
|
9e0c72 |
lineTo( calcX(x+dx, y, z+dz),
|
|
|
9e0c72 |
calcY(x+dx, y, z+dz) );
|
|
|
9e0c72 |
closePath();
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
fill(color);
|
|
|
9e0c72 |
moveTo( calcX(x, y, z+dz),
|
|
|
9e0c72 |
calcY(x, y, z+dz) );
|
|
|
9e0c72 |
lineTo( calcX(x+dx, y, z+dz),
|
|
|
9e0c72 |
calcY(x+dx, y, z+dz) );
|
|
|
9e0c72 |
lineTo( calcX(x+dx, y+dy, z+dz),
|
|
|
9e0c72 |
calcY(x+dx, y+dy, z+dz) );
|
|
|
9e0c72 |
lineTo( calcX(x, y+dy, z+dz),
|
|
|
9e0c72 |
calcY(x, y+dy, z+dz) );
|
|
|
9e0c72 |
closePath();
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
restoreState();
|
|
|
9e0c72 |
}
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
void setPoint(int i, int j, int size, double z) {
|
|
|
9e0c72 |
for(int ii = -size; ii <= size; ++ii)
|
|
|
9e0c72 |
for(int jj = -size; jj <= size; ++jj)
|
|
|
9e0c72 |
if ( i + ii >= 0 && i + ii < SIZE
|
|
|
9e0c72 |
&& j + jj >= 0 && j + jj < SIZE
|
|
|
9e0c72 |
&& ii*ii + jj*jj <= size*(size + 1) )
|
|
|
9e0c72 |
grid[0][i+ii][j+jj] = grid[1][i+ii][j+jj] = z;
|
|
|
9e0c72 |
}
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
void init() { }
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
void draw() {
|
|
|
9e0c72 |
double w = windowGetWidth();
|
|
|
9e0c72 |
double h = windowGetHeight();
|
|
|
9e0c72 |
double tm = windowGetSeconds();
|
|
|
9e0c72 |
|
|
|
9e0c72 |
saveState();
|
|
|
9e0c72 |
translate(w/2, h/2);
|
|
|
9e0c72 |
|
|
|
9e0c72 |
double smx = mouseTransformedX();
|
|
|
9e0c72 |
double smy = mouseTransformedY();
|
|
|
9e0c72 |
double mx = calcBackX(smx, smy);
|
|
|
9e0c72 |
double my = calcBackY(smx, smy);
|
|
|
9e0c72 |
|
|
|
9e0c72 |
if (keyWentDown("space"))
|
|
|
9e0c72 |
setPoint(randomNumber(0, SIZE-1), randomNumber(0, SIZE-1), 2, (randomFloat() - 0.5)*10);
|
|
|
9e0c72 |
|
|
|
9e0c72 |
double k = 1/sqrt(2);
|
|
|
9e0c72 |
double dt = 0.01;
|
|
|
9e0c72 |
if (fabs(simTm - tm) > 5) simTm = tm - dt/2;
|
|
|
9e0c72 |
while(simTm < tm) {
|
|
|
9e0c72 |
if (mouseDown("left") || mouseDown("right") || mouseDown("middle")) {
|
|
|
9e0c72 |
int i = (int)floor(mx + SIZE*0.5);
|
|
|
9e0c72 |
int j = (int)floor(my + SIZE*0.5);
|
|
|
9e0c72 |
setPoint(i, j, 4, mouseDown("left") ? 20 : mouseDown("right") ? -20 : 0);
|
|
|
9e0c72 |
}
|
|
|
9e0c72 |
|
|
|
9e0c72 |
int prevId = gridId;
|
|
|
9e0c72 |
gridId = 1 - gridId;
|
|
|
9e0c72 |
for(int i = 0; i < SIZE; ++i) {
|
|
|
9e0c72 |
for(int j = 0; j < SIZE; ++j) {
|
|
|
9e0c72 |
double z = grid[prevId][i][j];
|
|
|
9e0c72 |
double v = z - grid[gridId][i][j];
|
|
|
9e0c72 |
|
|
|
9e0c72 |
double f = 0;
|
|
|
9e0c72 |
double sum = 0;
|
|
|
9e0c72 |
if (i > 0 ) { f += grid[prevId][i-1][j] - z; sum += 1; }
|
|
|
9e0c72 |
if (i < SIZE-1) { f += grid[prevId][i+1][j] - z; sum += 1; }
|
|
|
9e0c72 |
if (j > 0 ) { f += grid[prevId][i][j-1] - z; sum += 1; }
|
|
|
9e0c72 |
if (j < SIZE-1) { f += grid[prevId][i][j+1] - z; sum += 1; }
|
|
|
9e0c72 |
if (i > 0 && j > 0 ) { f += k*(grid[prevId][i-1][j-1] - z); sum += k; }
|
|
|
9e0c72 |
if (i < SIZE-1 && j > 0 ) { f += k*(grid[prevId][i+1][j-1] - z); sum += k; }
|
|
|
9e0c72 |
if (i > 0 && j < SIZE-1) { f += k*(grid[prevId][i-1][j+1] - z); sum += k; }
|
|
|
9e0c72 |
if (i < SIZE-1 && j < SIZE-1) { f += k*(grid[prevId][i+1][j+1] - z); sum += k; }
|
|
|
9e0c72 |
if (sum > 0) f /= sum;
|
|
|
9e0c72 |
|
|
|
9e0c72 |
grid[gridId][i][j] = z + (v + 0.1*f)*0.99;
|
|
|
9e0c72 |
}
|
|
|
9e0c72 |
}
|
|
|
9e0c72 |
simTm += dt;
|
|
|
9e0c72 |
}
|
|
|
9e0c72 |
|
|
|
9e0c72 |
for(int i = 0; i < SIZE; ++i)
|
|
|
9e0c72 |
for(int j = SIZE-1; j >= 0; --j)
|
|
|
9e0c72 |
drawBox( i - SIZE*0.5 - 0.5,
|
|
|
9e0c72 |
j - SIZE*0.5 - 0.5,
|
|
|
9e0c72 |
-50,
|
|
|
9e0c72 |
1, 1, 50 + grid[gridId][i][j],
|
|
|
9e0c72 |
COLOR_AQUA );
|
|
|
9e0c72 |
|
|
|
9e0c72 |
restoreState();
|
|
|
9e0c72 |
|
|
|
9e0c72 |
saveState();
|
|
|
9e0c72 |
noFill();
|
|
|
9e0c72 |
text(10, 10, "try left and right mouse buttons");
|
|
|
9e0c72 |
restoreState();
|
|
|
9e0c72 |
}
|
|
|
9e0c72 |
|
|
|
9e0c72 |
|
|
|
9e0c72 |
int main() {
|
|
|
9e0c72 |
windowSetTitle("Water");
|
|
|
9e0c72 |
windowSetVariableFrameRate();
|
|
|
9e0c72 |
windowSetResizable(TRUE);
|
|
|
9e0c72 |
windowSetInit(&init);
|
|
|
9e0c72 |
windowSetDraw(&draw);
|
|
|
9e0c72 |
windowRun();
|
|
|
9e0c72 |
return 0;
|
|
|
9e0c72 |
}
|