Monthly Archives: October 2013

Gravity Golf

Many moons ago, in 2009, I was on holiday with the family in New Zealand. I made a little planet gravity game thing in Processing. The game is called Gravity Golf.

Recent advances in Processing means that I can publish it on the web. The aim is to find a really cool path of a particle around whatever planets there are to the pink target. The longest duration path is the one that is rendered.

GravityGolf

The controls are:

  • Left Click – Launch Single Projectile
  • Right Click – add/remove planet
  • Space – Move Arrow
  • T – Move Target
  • R – Launch Randomly
  • M – Rapid (Machine Gun) Launch
  • Z – Reset to a random configuration
  • H – Display this help

Enjoy!

Diamond-Square Algorithm in Processing

I was trying to do a plasma height map using the midpoint displacement algorithm. But there were some weird grid artifacts.

PlasmaSo I looked up the Diamond-Square Algorithm and implemented it and seems to look better.

DiamondSquare

 I’ve also spotted a plasma map hidden in GIMP too.

GimpPlasma

 

Here is the Diamond-Square code for Processing

void setup() {
 size(N, N);
 colorMode(HSB, 360, 1.0, 1.0);
 noSmooth();
 noLoop();
 
 gHeights = new float[N][N];
 for (int i = 0; i < N; i++) {
 for (int j = 0; j < N; j++) {
 gHeights[i][j] = -1000.0;
 }
 }
}
final int N = 2*2*2*2*2*2*2*2;
final float CHAOS = 0.5;
float [][] gHeights;
float getHeight(int x, int y) {
 int iX = (x + N) % N;
 int iY = (y + N) % N;
 return gHeights[iX][iY];
}
void draw() {
 println("Hello");
 populateRect();
 drawRect(); 
}
void populateRect() {
 // init corner
 gHeights[0][0] = random(0.0, 1.0);
 
 int d = N / 2;
 
 while (d > 0) {
 // set middles of the squares of size d
 setSquareCentres(d);
 setDiamondCentres(d);
 d /= 2;
 }
 
 //normaliseHeights();
}
void normaliseHeights() {
 // scale all heights to be between 0.0 and 1.0
 float maximum = getHeight(0,0);
 float minimum = getHeight(0,0);
 for (int x = 0; x < N; x++) {
 for (int y = 0; y < N; y++) {
 float z = gHeights[x][y];
 if (z < minimum) minimum = z;
 if (z > maximum) maximum = z;
 }
 }
 
 float d = maximum - minimum;
 println(str(d));
 println(str(maximum));
 println(str(minimum));
 for (int x = 0; x < N; x++) {
 for (int y = 0; y < N; y++) {
 float z = gHeights[x][y];
 gHeights[x][y] = (z - minimum) / d;
 }
 }
 
 
}
void setSquareCentres(int d) {
 int d2 = d + d;
 for (int x = 0; x < N; x += d2) {
 for (int y = 0; y < N; y += (d + d)) {
 int xMid = x + d;
 int yMid = y + d;
 if (gHeights[xMid][yMid] < -100.0) {
 gHeights[xMid][yMid] = (getHeight(x, y) + getHeight(x + d2, y)
 + getHeight(x, y + d2) + getHeight(x + d2, y + d2)) / 4.0
 + random(-CHAOS, CHAOS) * d2 / N;
 
 gHeights[xMid][yMid] = constrain(gHeights[xMid][yMid], 0.0, 1.0);
 }
 }
 }
}
void setDiamondCentres(int d) {
 int d2 = d + d;
 for (int x = 0; x < N; x += d2) {
 for (int y = 0; y < N; y += (d + d)) {
 int xMid = x + d;
 int yMid = y + d;
 if (gHeights[xMid][y] < -100.0) {
 gHeights[xMid][y] = (getHeight(x, y) + getHeight(x + d2, y)
 + getHeight(xMid, yMid) + getHeight(xMid, y - d)) / 4.0
 + random(-CHAOS, CHAOS) * d2 / N;
 gHeights[xMid][y] = constrain(gHeights[xMid][y], 0.0, 1.0);
 }
 if (gHeights[x][yMid] < -100.0) {
 gHeights[x][yMid] = (getHeight(x, y) + getHeight(x, y + d2)
 + getHeight(xMid, yMid) + getHeight(x - d, y)) / 4.0
 + random(-CHAOS, CHAOS) * d2 / N;
 gHeights[x][yMid] = constrain(gHeights[x][yMid], 0.0, 1.0);
 }
 }
 }
}
void drawRect() {
 for (int x = 0; x < N; x++) {
 for (int y = 0; y < N; y++) {
 color c = colourMap(gHeights[x][y]);
 stroke(c);
 point(x, y);
 }
 }
}
color colourMap(float x) {
 return color(230, x, 1.0);
}