We are about to switch to a new forum software. Until then we have removed the registration on this forum.
This was supposed to be a celluar automata kind of thing but it was blinking so annoyingly.
Got a smoother turbulence thing going and added random painting to it which looks pretty cool in motion.
https://youtube.com/watch?v=cd-ZNymt6Ko&feature=youtu.be
newer video -> https://youtube.com/watch?v=cbCyq5RMXLk
leftclick, paint, rightclick erase
Update2,
Faster version any key changes "rule"
int button;
int speed;
int paint;
int xyz;
int vdit;
int[] field;
int[] b;
boolean closerThan(int distance,int x0,int y0){
int dx = x0-mouseX; dx*=dx;
int dy = y0-mouseY; dy*=dy;
return dx+dy<distance;}
int sts (int l){ return ((l%4==0)?0:2)*((floor(l/4)%2==1)?-1:1);}
int[] pbox(int n, int layer){
int px,py,xt,yt; xt=yt=0;
px=(layer%2==0)?0:1;
py=(layer<=1)?0:1;
if(n<=7){ xt=px==0?1:-1;}
else { yt=py==0?1:-1;}
xt += sts(n);
yt += sts(n+2);
return new int[]{xt,yt};
}
int[] pboxresult = new int[2];
int[][] overview = {
{ 1,2,3,2,3,0,3,-2, 1,-2,-1,-2,-1,0,-1,2,0,3,2,3,2, 1,2,-1,0,-1,-2,-1,-2, 1,-2,3},
{-1,2,1,2,1,0,1,-2,-1,-2,-3,-2,-3,0,-3,2,0,3,2,3,2, 1,2,-1,0,-1,-2,-1,-2, 1,-2,3},
{ 1,2,3,2,3,0,3,-2, 1,-2,-1,-2,-1,0,-1,2,0,1,2,1,2,-1,2,-3,0,-3,-2,-3,-2,-1,-2,1},
{-1,2,1,2,1,0,1,-2,-1,-2,-3,-2,-3,0,-3,2,0,1,2,1,2,-1,2,-3,0,-3,-2,-3,-2,-1,-2,1}
};
int[][] compare = new int[4][32];
int[][] transform = new int[4][32];
long RULE;
long randomlong(){
long result = floor(random(0,65536));
for(int i=0;i<3;i++){
result<<= 24;
result+=floor(random(0,16777216));
}
return result;
}
void compare_update(){
for(int i=0; i<4; i++){
for(int j=0; j<16; j++){
compare[i][j*2 ] = overview[i][j*2 ]; // map(overview[i][j*2 ],-width,width,-1,1);
compare[i][j*2+1] = overview[i][j*2+1]; // map( -height,height,-1,1);
}}}
void transform_update(){
for(int i=0; i<4; i++){
RULE = randomlong();
for(int j=0; j<16; j++){
pboxresult = pbox(int((RULE>>(j*4))&15),i);
transform[i][j*2 ]=pboxresult[0];
transform[i][j*2+1]=pboxresult[1];
}}}
void setup() {
size(384, 384);
xyz=width*height;
field=new int[xyz];
b=new int[xyz];
loadPixels();
compare_update();
new_rule();
}
void keyPressed(){
new_rule();
}
void new_rule(){
transform_update();
}
int frag(int p){
int x=p%width;
int y=p/width;
int comp=0;
int mine;
if(mousePressed && closerThan(speed,x,y)){
return paint;
} else {
int mylayer = (x%2==0?0:1)+(y%2==0?0:2);
mine = b[p];
for(int i =0; i<15; i++){
comp +=((b[((x+compare[mylayer][i*2]+(y+compare[mylayer][i*2+1])*width)+xyz)%xyz]<mine)?1:0);
}
return b[((x+transform[mylayer][comp*2]+(y+transform[mylayer][comp*2+1])*width)+xyz)%xyz];
}
}
void worker_a(){
for(int p=0; p<xyz; p++){
b[p]=pixels[p]=field[p];
}
}
void worker_b(){
for(int p=0; p<xyz; p++){
field[p]=frag(p);
}
}
void draw(){
println(frameRate);
if(mousePressed){
if( mouseButton == LEFT ){
button=1;
paint=floor(random(#000000,#ffffff));
} else{button =2; paint=#fffffe;}
}
else { button = 0; }
speed = int(sq(mouseX-pmouseX)+sq(mouseY-pmouseY)); // intentionally not using sqrt()
rect(0,0,width,height);
thread("worker_a");
thread("worker_b");
updatePixels();
}
Object oriented version
int paint;
int dis;
int speed;
int rulecounter;
int smooth = 1;
int xyz=256;
field g;
int randomcolor(){return floor(random(#000000,#ffffff));}
void setup(){size(256,256,P2D);g = new field();loadPixels();}
void draw() {
speed=floor(dist(pmouseX,pmouseY,mouseX,mouseY));
if(mousePressed){
if(mouseButton==LEFT) {
paint = randomcolor();
} else { paint = #ffffff; }
}
g.update();
g.display();
if(rulecounter++%100==0){g.randomrule();}
}
class field {
subdivision[][] rid;
long[] RULE;
field() {
RULE = new long[4];
randomrule();
int[] VAL;
rid = new subdivision[xyz][xyz];
for (int y = 0 ; y < xyz; y++) {
for (int x = 0 ; x < xyz; x++) {
VAL = new int []{#ffffff,#ffffff,#ffffff,#ffffff};
rid[x][y] = new subdivision(x,y,VAL,RULE);
}}
for (int y = 0 ; y < xyz; y++) {
for (int x = 0 ; x < xyz; x++) {
rid[x][y].set_neighbours(this.rid);
}}
}
long randomlong(){
long result = floor(random(0,65536));
for(int i=0;i<3;i++){
result<<= 24;
result+=floor(random(0,16777216));
}
return result;
}
void randomrule(){
RULE[0] = randomlong();
RULE[1] = randomlong();
RULE[2] = randomlong();
RULE[3] = randomlong();
}
void update(){
for (int y=0;y<xyz;y++){
for (int x=0;x<xyz;x++){
rid[x][y].update_pixels();
}}
}
void display(){
updatePixels();
for (int y=0;y<xyz;y++){
for (int x=0;x<xyz;x++){
rid[x][y].buffer();
}}
}
}
class subdivision{
long [] rule;
int [] ra; // results array
int [] val; // value array
int x,y; // coordinate of the pixel
int xy; // x,y in one dimensional framebuffer
int [][] neighbours;
subdivision(int X, int Y, int[]VAL, long[]RULE){
x=X; y=Y; val=VAL; rule=RULE;
xy = x+xyz*y;
neighbours = new int [8][4];
ra = new int [4];
}
void set_neighbours(subdivision[][] rid){
int x1,x3,y1,y3;
for ( int i=0; i < 4; i++) {
x1=(x+1)%xyz; x3=(x+xyz-1)%xyz; // 3 is -1 as it "wraps around"
y1=(y+1)%xyz; y3=(y+xyz-1)%xyz;
// surrounding pixels clockwise
neighbours[ 0] = rid[x1][y3].val;
neighbours[ 1] = rid[x1][ y].val;
neighbours[ 2] = rid[x1][y1].val;
neighbours[ 3] = rid[ x][y1].val;
neighbours[ 4] = rid[x3][y1].val;
neighbours[ 5] = rid[x3][ y].val;
neighbours[ 6] = rid[x3][y3].val;
neighbours[ 7] = rid[ x][y3].val;
}
}
/* Thanks to u/ErasmusDarwin */
int blackbox(long n,long rule){return int((rule>>(n*4))&15);}
int pixel(int foo, int bar) {
if (smooth <= 0){return foo;} else if(smooth >= 8){return bar;} else{
int r,g,b;
r = ( ( (foo >> 16 & 0xFF) * ((1 << smooth) -1) + (bar >> 16 & 0xFF) ) >> smooth ) << 16;
g = ( ( (foo >> 8 & 0xFF) * ((1 << smooth) -1) + (bar >> 8 & 0xFF) ) >> smooth ) << 8;
b = ( ( (foo & 0xFF) * ((1 << smooth) -1) + (bar & 0xFF) ) >> smooth );
return r+g+b;
}
}
int merge(){
int r,g,b;
r = (((ra[0] >> 16 & 0xFF) + (ra[1] >> 16 & 0xFF) + (ra[2] >> 16 & 0xFF) + (ra[3] >> 16 & 0xFF)) >> 2) << 16;
g = (((ra[0] >> 8 & 0xFF) + (ra[1] >> 8 & 0xFF) + (ra[2] >> 8 & 0xFF) + (ra[3] >> 8 & 0xFF)) >> 2) << 8;
b = ((ra[0] & 0xFF) + (ra[1] & 0xFF) + (ra[2] & 0xFF) + (ra[3] & 0xFF)) >> 2;
return #000000+r+g+b;
}
void update_pixels() {
dis=floor(dist(mouseX,mouseY,x,y));
int c; // comparission
int t; // transformation
int r; // result
int top, bottom, layer; //
for (int l=0; l<4; l++){
if(mousePressed) {
smooth = max(0,min(8,dis >> 6));
} else {
smooth=0;
}
if(mousePressed && dis<1+speed) {
r = paint;
} else {
top = (l+1)%4; bottom=(l+3)%4;
c=0;
for (int n=0; n<8; n++){
if ( val[l] > neighbours[ n][top] ) {c++;}
if ( val[l] > neighbours[ n][bottom] ) {c++;}
}
t=blackbox(c,rule[l]);
if (t<=7){ layer = top; } else { t-=8; layer=bottom; }
r=neighbours[t][layer];
}
ra[l]=pixel(r,val[l]);
}
pixels[xy] = merge();
}
void buffer() {
for (int l=0; l<4; l++) {
val[l]=ra[l];
}
}
}
Original version
/* Thanks to u/ErasmusDarwin for map function*/
//int rule_map(int n,int rule){return(rule>>(n*2))&3;} 4^4, rules 2^8
//int rule_map(int n,int rule){return int((rule>>(n*3))&7);} 8^8, rules 2^24
int rule_map(long n,long rule){return int((rule>>(n*4))&15);} // 16^16, 2^64 rules
void rla(){
for(int i=0;i<4;i++){
rule[i]=randomlong();
}
}
long randomlong(){
long result = floor(random(0,65536));
for(int i=0;i<3;i++){
result<<= 24;
result+=floor(random(0,16777216));
}
return result;
}
int rlac,smooth = 1;
class gray { gray(){}
int pixel(int[]ca) {
if (smooth == 0){return ca[3];} else{
int r,g,b;
r = ( ( (ca[3] >> 16 & 0xFF) * ((1 << smooth) -1) + (ca[0] >> 16 & 0xFF) ) >> smooth ) << 16;
g = ( ( (ca[3] >> 8 & 0xFF) * ((1 << smooth) -1) + (ca[0] >> 8 & 0xFF) ) >> smooth ) << 8;
b = ( ( (ca[3] & 0xFF) * ((1 << smooth) -1) + (ca[0] & 0xFF) ) >> smooth );
return r+g+b;
}
}
int merge(int[]ca) {
int r,g,b;
r = (((ca[0] >> 16 & 0xFF) + (ca[1] >> 16 & 0xFF) + (ca[2] >> 16 & 0xFF) + (ca[3] >> 16 & 0xFF)) >> 2) << 16;
g = (((ca[0] >> 8 & 0xFF) + (ca[1] >> 8 & 0xFF) + (ca[2] >> 8 & 0xFF) + (ca[3] >> 8 & 0xFF)) >> 2) << 8;
b = ((ca[0] & 0xFF) + (ca[1] & 0xFF) + (ca[2] & 0xFF) + (ca[3] & 0xFF)) >> 2;
return r+g+b;
}
}
gray gs = new gray();
int randomcolor(){return floor(random(0x0,0xffffff));}
int paint = 0x0;
int swap,cc,xyz=256;
long[] rule = new long [4];
int[][][][] fields = new int[2][4][xyz][xyz];
int[]ca=new int[4];
int[]aa=new int[4];
void clear() {
for(int b=0;b<2;b++){
for(int d=0;d<4;d++){
for (int x=0;x < xyz; x++) {
for (int y = 0; y < xyz; y++) {
fields[b][d][x][y] = #ffffff;}}}}}
int algorithm(int d,int x0,int y0){
int dis=floor(dist(mouseX,mouseY,x0,y0));
int speed=floor(dist(pmouseX,pmouseY,mouseX,mouseY));
int [][]n1=fields[swap][(d+4+1)%4];
int [][]n2=fields[swap][(d+4+3)%4];
int m=fields[swap][d][x0][y0];
aa[0]=aa[1]=aa[2]=aa[3]=m & 0xfffffe;
if(mousePressed){
if(dis<1+speed){if(mouseButton==LEFT){return paint;}else{return 0xffffff;}}
smooth=max(0,min(8,dis >> 6));
} else{smooth=0;}
int t=0*0;
int y1=(y0+1)%xyz,y3=(y0+xyz-1)%xyz,
x1=(x0+1)%xyz,x3=(x0+xyz-1)%xyz;
int c = max(0,(((m>n1[x0][y0])?1:0)+
((m>n1[x0][y1])?1:0)+
((m>n1[x0][y3])?1:0)+
((m>n1[x1][y0])?1:0)+
((m>n1[x3][y0])?1:0)+
((m>n2[x0][y0])?1:0)+
((m>n2[x0][y1])?1:0)+
((m>n2[x0][y3])?1:0)+
((m>n2[x1][y0])?1:0)+
((m>n2[x3][y0])?1:0))-1);
switch((rule_map(c,rule[d]))%16){
case 0:t= n1[x0][y1];break;
case 1:t= n1[x0][y3];break;
case 2:t= n1[x1][y0];break;
case 3:t= n1[x3][y0];break;
case 4:t= n1[x1][y1];break;
case 5:t= n1[x3][y3];break;
case 6:t= n1[x3][y1];break;
case 7:t= n1[x1][y3];break;
case 8:t= n2[x0][y1];break;
case 9:t= n2[x0][y3];break;
case 10:t= n2[x1][y0];break;
case 11:t= n2[x3][y0];break;
case 12:t= n2[x1][y1];break;
case 13:t= n2[x3][y3];break;
case 14:t= n2[x3][y1];break;
case 15:t= n2[x1][y3];break;
default:break;}
aa[3]=t;
return gs.pixel(aa);
}
void setup(){size(256,256,P2D);rla();clear();loadPixels();}
void draw() { for (int x=0;x<xyz;x++){
for (int y=0;y<xyz;y++){
for (int d=0;d<4;d++){
fields[(swap+1)%2][d][x][y]=ca[d]=algorithm(d,x,y);
if(d==3){pixels[x+xyz*y]=gs.merge(ca);}}}
} updatePixels(); paint = randomcolor();
if(swap==0){swap=1;}else{swap=0;}
if(rlac++%100==0){rla();}
}
Comments
Shame about the blinking but as you say, some nice patterns develop. =D>