/** A 3D hexagonal labyrinth, that is exported as a STL-File. by guru */ import processing.opengl.*; import unlekker.data.*; int [][] d; String exportFileName = "labyrinth.stl"; int WIDTH=6; void setup() { d = generate(WIDTH); size(600, 600, OPENGL); noLoop(); } void draw() { beginRaw("unlekker.data.STL", exportFileName); background(128); fill(255); translate( width/2,0); float di = width/d.length; float h = sqrt( 4 * sq(di)/3); int m = (d.length+1)/2-1; for ( int r = 0; r < d.length; r++) { float s = di * d[r].length; for ( int c = 0; c < d[r].length; c++) { float x = di/2- s/2 + di * c; float y = h/2 + r * h*.75; beginShape(); for( int i=0; i<6; i++) { vertex( x + sin( radians(120 + i*60))*h/2, y + cos( radians(120 +i*60))*h/2, 0 ); } endShape( CLOSE ); beginShape(); for( int i=0; i<6; i++) { vertex( x + sin( radians(120 + i*60))*h/2, y + cos( radians(120 +i*60))*h/2, -5 ); } endShape( CLOSE ); for ( int i = 0; i < 6; i++) { beginShape(QUADS); vertex( x + sin( radians(120 + i*60))*h/2, y + cos( radians(120 +i*60))*h/2, -5 ); vertex( x + sin( radians(120+(i+1)*60))*h/2, y + cos( radians(120+(i+1)*60))*h/2, -5); vertex( x + sin( radians(120+(i+1)*60))*h/2, y + cos( radians(120+(i+1)*60))*h/2, 0); vertex( x + sin( radians(120 + i*60))*h/2, y + cos( radians(120 +i*60))*h/2, 0); endShape( CLOSE ); } for ( int i = 0; i < 6; i++) { if (( d[r][c] & int(pow(2,i))) == 0 ) { float r1 = h/2-5; float r2 = h/2; beginShape(QUADS); vertex( x + sin( radians(120 + i*60))*r1, y + cos( radians(120 +i*60))*r1, 0 ); vertex( x + sin( radians(120+(i+1)*60))*r1, y + cos( radians(120+(i+1)*60))*r1, 0); vertex( x + sin( radians(120+(i+1)*60))*r1, y + cos( radians(120+(i+1)*60))*r1, h); vertex( x + sin( radians(120 + i*60))*r1, y + cos( radians(120 +i*60))*r1, h ); endShape( CLOSE ); beginShape(QUADS); vertex( x + sin( radians(120 + i*60))*r1, y + cos( radians(120 +i*60))*r1, h ); vertex( x + sin( radians(120+(i+1)*60))*r1, y + cos( radians(120+(i+1)*60))*r1, h); vertex( x + sin( radians(120+(i+1)*60))*r2, y + cos( radians(120+(i+1)*60))*r2, h); vertex( x + sin( radians(120 + i*60))*r2, y + cos( radians(120 +i*60))*r2, h ); endShape( CLOSE ); beginShape(QUADS); vertex( x + sin( radians(120 + i*60))*r1, y + cos( radians(120 +i*60))*r1, 0 ); vertex( x + sin( radians(120+(i+1)*60))*r1, y + cos( radians(120+(i+1)*60))*r1, 0); vertex( x + sin( radians(120+(i+1)*60))*r2, y + cos( radians(120+(i+1)*60))*r2, 0); vertex( x + sin( radians(120 + i*60))*r2, y + cos( radians(120 +i*60))*r2, 0 ); endShape( CLOSE ); beginShape(QUADS); vertex( x + sin( radians(120 + i*60))*r1, y + cos( radians(120 +i*60))*r1, 0 ); vertex( x + sin( radians(120 + i*60))*r2, y + cos( radians(120 +i*60))*r2, 0 ); vertex( x + sin( radians(120 + i*60))*r2, y + cos( radians(120 +i*60))*r2, h ); vertex( x + sin( radians(120 + i*60))*r1, y + cos( radians(120 +i*60))*r1, h ); endShape( CLOSE ); beginShape(QUADS); vertex( x + sin( radians(120+(i+1)*60))*r1, y + cos( radians(120+(i+1)*60))*r1, 0); vertex( x + sin( radians(120+(i+1)*60))*r2, y + cos( radians(120+(i+1)*60))*r2, 0); vertex( x + sin( radians(120+(i+1)*60))*r2, y + cos( radians(120+(i+1)*60))*r2, h); vertex( x + sin( radians(120+(i+1)*60))*r1, y + cos( radians(120+(i+1)*60))*r1, h); endShape( CLOSE ); if (( r == 0 && (i == 0 || i == 1)) || ( r < m && c == 0 && (i == 1 || i == 2 )) || ( r < m && c == d[r].length-1 && ( i == 0 || i == 5 )) || ( r == m && c == 0 && ( i == 1 || i == 2 || i == 3 )) || ( r == m && c == d[r].length-1 && ( i == 0 || i == 5 || i == 4)) || ( r > m && c == 0 && (i == 2 || i == 3 )) || ( r > m && c == d[r].length-1 && ( i == 5 || i == 4 )) || ( r == d.length-1 && (i == 3 || i == 4)) ) { beginShape(QUADS); vertex( x + sin( radians(120 + i*60))*r2, y + cos( radians(120 +i*60))*r2, 0 ); vertex( x + sin( radians(120+(i+1)*60))*r2, y + cos( radians(120+(i+1)*60))*r2, 0); vertex( x + sin( radians(120+(i+1)*60))*r2, y + cos( radians(120+(i+1)*60))*r2, h); vertex( x + sin( radians(120 + i*60))*r2, y + cos( radians(120 +i*60))*r2, h ); endShape( CLOSE ); } } } } } endRaw(); } int[][] generate( int l ) { int[][] res = new int[2*l-1][]; for ( int r =0; r<2*l-1; r++) { int c = l + ( r < l-1 ? r : 2*l-2-r); res[r] = new int[ c]; for( int i = 0; i < c; i++) { res[r][i] = 0; } } carve(0,0,res); return res; } void carve( int r, int c, int[][] d) { int[] dirs = shuffle(); for( int i=0; i < 6;i++) { int dir = dirs[i]; int nr = r + (( dir == 32 || dir == 4 ) ? 0 : ( dir < 4 ? -1 : 1 )); int nc = c; int m = (d.length+1)/2-1; if (r < m) { if ( dir == 1 ) { nc = c; } if ( dir == 2 ) { nc = c - 1; } if ( dir == 4 ) { nc = c -1; } if ( dir == 8 ) { nc = c; } if ( dir == 16 ) { nc = c + 1; } if ( dir == 32 ) { nc = c + 1; } } else if ( r == m ) { if ( dir == 1 ) { nc = c; } if ( dir == 2 ) { nc = c - 1; } if ( dir == 4 ) { nc = c -1; } if ( dir == 8 ) { nc = c -1; } if ( dir == 16 ) { nc = c; } if ( dir == 32 ) { nc = c + 1; } } else { if ( dir == 1 ) { nc = c +1; } if ( dir == 2 ) { nc = c; } if ( dir == 4 ) { nc = c -1; } if ( dir == 8 ) { nc = c -1; } if ( dir == 16 ) { nc = c; } if ( dir == 32 ) { nc = c + 1; } } // println( "X, Y = " + nx + " " + ny ); if ( nr >= 0 && nr < d.length && nc >= 0 && nc < d[nr].length && d[nr][nc] == 0 ) { d[r][c] = d[r][c] | dir; d[nr][nc] = d[nr][nc] | odir(dir); carve(nr,nc,d); } } } int[] shuffle() { int[] o = new int[] { 1,2,4,8,16,32 }; int res[] = new int[6]; for( int i =0; i < 6; i++) { int ri = int(random(6)); while ( o[ri] == 0 ) { ri = int(random(6)); } res[i] = o[ri]; o[ri] = 0; } return res; } int odir( int dir ) { if (dir == 1) return 8; if (dir == 8) return 1; if (dir == 2) return 16; if (dir == 16) return 2; if (dir == 4) return 32; if (dir == 32) return 4; return 0; } void keyPressed() { d = generate( WIDTH); }