Repository: baku89/Subete-ga-F-ni-naru-ED Branch: master Commit: 73c9f11895ef Files: 59 Total size: 150.4 KB Directory structure: gitextract_o1id6m_a/ ├── .gitignore ├── LICENSE ├── golly/ │ ├── export-otca-metapixels.py │ ├── export_large.py │ ├── golly_python_script_to_output_meta-life_animation.py │ ├── last-shiki.py │ ├── load-image.py │ ├── rotate.py │ └── step_generation.py ├── others/ │ ├── ResizeBorder.pbk │ ├── ResizeBorderTrim.pbk │ └── p5.sh ├── p5/ │ ├── cell_division_test/ │ │ ├── CellDivision.pde │ │ ├── cell_division_test.pde │ │ └── util.pde │ ├── cubist/ │ │ ├── cubist.pde │ │ ├── rect.pde │ │ ├── ui.pde │ │ └── util.pde │ ├── cubist_galaxy/ │ │ ├── cubist_galaxy.pde │ │ ├── rect.pde │ │ ├── ui.pde │ │ └── util.pde │ ├── dla/ │ │ ├── Particle.pde │ │ ├── Point.pde │ │ ├── dla.pde │ │ └── util.pde │ ├── dla_animate/ │ │ ├── dla_animate.pde │ │ ├── ui.pde │ │ └── util.pde │ ├── filling/ │ │ ├── filling.pde │ │ └── util.pde │ ├── life_like/ │ │ ├── ca.pde │ │ ├── life_like.pde │ │ └── util.pde │ ├── life_like_transition/ │ │ ├── ca.pde │ │ ├── life_like_transition.pde │ │ ├── rules.pde │ │ ├── settings.pde │ │ └── util.pde │ ├── morphing/ │ │ ├── morphing.pde │ │ └── util.pde │ ├── shiki/ │ │ ├── morph.pde │ │ ├── shiki.command │ │ ├── shiki.pde │ │ ├── ui.pde │ │ ├── uiConverter.pde │ │ └── util.pde │ └── wolfram/ │ ├── CA.pde │ └── wolfram.pde ├── p5js/ │ ├── cell-diffuse/ │ │ ├── index.html │ │ ├── save-sequence.php │ │ ├── sketch-draw-maze.js │ │ └── sketch.js │ └── randomized-prizm/ │ ├── index.html │ ├── save-sequence.php │ ├── sketch-draw-maze.js │ └── sketch.js └── readme.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ **/out/* ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Baku Hashimoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: golly/export-otca-metapixels.py ================================================ from __future__ import division import golly as g from PIL import Image from math import floor, ceil, log import os import json #--------------------------------------------- # settings exportDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/golly-exported" name = "otca" duration = None#8 #int( g.getgen() ) isReset = True expand = 0 bound = [0, 0, 2048, 2048] otcaInterval = 35328 otcaStep = 64 step = otcaInterval / otcaStep #--------------------------------------------- # settings def log( data ): g.note( json.dumps(data) ) def getPalette(): colors = g.getcolors() palette = {} for i in xrange( 0, len(colors), 4 ): state = colors[ i ] rVal = colors[ i + 1 ] gVal = colors[ i + 2 ] bVal = colors[ i + 3 ] palette[ state ] = ( rVal, gVal, bVal ) return palette def main( step = 1, start = 0 ): global bound, expand, duration # get selection and set to boundary bound = g.getselrect() if duration == None: duration = int( g.getgen() ) if isReset: g.reset() if len( bound ) == 0: g.note( "No selection." ) g.exit() # get current Golly states if bound == None: bound[ 0 ] -= expand bound[ 1 ] -= expand bound[ 2 ] += expand * 2 bound[ 3 ] += expand * 2 left = bound[ 0 ] top = bound[ 1 ] width = bound[ 2 ] height = bound[ 3 ] palette = getPalette() cells = g.getcells( bound ) isMultiStates = len(cells) % 2 == 1 cellW = 3 if isMultiStates else 2 # create image and destination directory dstDir = "%s/%s" % (exportDir, name) if not os.path.exists( dstDir ): os.makedirs( dstDir ) # else: # g.note( "destination folder already exists" ) # g.exit() # log( cells ) for i in xrange( duration ): g.show( "Processing... %d / %d" % (i+1, duration) ) g.run( 1 ) g.update() cells = g.getcells( bound ) # create image img = Image.new( "RGB", ( width, height ) ) cellLen = int( floor( len(cells)/cellW ) * cellW ) for i in xrange( 0, cellLen, cellW ): x = cells[ i ] y = cells[ i + 1 ] state = cells[ i + 2 ] if isMultiStates else 1 img.putpixel( (x-left, y-top), palette[state] ) # save gen = int( g.getgen() ) img.save( "%s/%s_%08d.png" % (dstDir, name, gen) ) #--------------------------------------------- # main main() ================================================ FILE: golly/export_large.py ================================================ from __future__ import division import golly as g from PIL import Image from math import floor, ceil, log import os import json #--------------------------------------------- # settings exportDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/golly-exported/otca" # common # duration = 147 #int( g.getgen() ) otcaDur = 35328 worldWidth = 30730 # 1/16x (1920) duration = 64 ratio = 8 subdiv = 1 skipBound = 1 # skipFrame = int(genDur / duration) # ad # name = "ad_x%02d" % ratio # bound = [4, 3, 1, 1] # da # name = "da_x%02d" % ratio # bound = [5, 2, 1, 1] # dd # name = "dd_x%02d" % ratio # bound = [0, 0, 1, 1] # aa name = "aa_x%02d" % ratio bound = [8, 3, 1, 1] bound[0] -= 8 bound[1] -= 8 # 1/8x # ratio = 8 # subdiv = 2 # skipBound = 2 # skipFrame = 1000 # bound = [2, 2, 11, 11] # 1/4x # ratio = 4 # subdiv = 2 # skipBound = 2 # skipFrame = 1000 # bound = [2, 2, 9, 8] # 1/2x # ratio = 2 # subdiv = 2 # skipBound = 2 # skipFrame = 1000 # bound = [3, 3, 6, 6] # 1/1x # ratio = 1 # subdiv = 1 # skipBound = 1 # skipFrame = 1 # dead or alive # bound = [0, 0, 1, 1] # mode = "dead" # bound = [2, 5, 1, 1] # mode = "aliv" #--------------------------------------------- # settings def log( data ): g.note( json.dumps(data) ) def getPalette(): colors = g.getcolors() palette = {} for i in xrange( 0, len(colors), 4 ): state = colors[ i ] rVal = colors[ i + 1 ] gVal = colors[ i + 2 ] bVal = colors[ i + 3 ] palette[ state ] = ( rVal, gVal, bVal ) return palette def main( step = 1, start = 0 ): global bound, expand g.reset() g.run(otcaDur) # get current Golly states cellWidth = 2048 bound[ 0 ] = bound[0] * cellWidth bound[ 1 ] = bound[1] * cellWidth bound[ 2 ] = bound[2] * cellWidth bound[ 3 ] = bound[3] * cellWidth left = bound[ 0 ] top = bound[ 1 ] width = bound[ 2 ] height = bound[ 3 ] palette = getPalette() cells = g.getcells( [0, 0, 1, 1] ) isMultiStates = len(cells) % 2 == 1 cellW = 2 # create image and destination directory dstDir = "%s/%s" % (exportDir, name) if not os.path.exists( dstDir ): os.makedirs( dstDir ) # else: # g.note( "destination folder already exists" ) # g.exit() imgWidth = int( width / ratio ) imgHeight = int ( height / ratio ) boundWidth = ratio / subdiv pb = [0, 0, boundWidth, boundWidth] # pixel bound i = x = y = bx = by = 0 frameCount = 0 step = int(otcaDur / duration) for i in xrange(0, duration): g.show("Processing... %d / %d" % (i+1, duration)) g.run(step) g.update() img = Image.new("RGB", (imgWidth, imgHeight)) for y in xrange(imgHeight): for x in xrange(imgWidth): for by in xrange(0, subdiv, skipBound): for bx in xrange(0, subdiv, skipBound): pb[0] = left + x * ratio + bx * boundWidth pb[1] = top + y * ratio + by * boundWidth cells = g.getcells(pb) if len( cells ) > 0: img.putpixel((x, y), (255, 255, 255)) break else: continue break # save # img.save( "%s/%s_%02dx_%s_%08d.png" % (dstDir, name, ratio, mode, i) ) # img.save( "%s/%s_%02dx_%08d.png" % (dstDir, name, ratio, i) ) img.save("%s/%s_%04d.png" % (dstDir, name, i)) g.show("Done.") #--------------------------------------------- # main main() ================================================ FILE: golly/golly_python_script_to_output_meta-life_animation.py ================================================ from __future__ import division import golly as g from PIL import Image from math import floor, ceil, log import os import json #--------------------------------------------- # settings exportDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/golly-exported" name = "galaxy-sample" duration = 8 #int( g.getgen() ) isReset = True expand = 0 #--------------------------------------------- # settings def log( data ): g.note( json.dumps(data) ) def getPalette(): colors = g.getcolors() palette = {} for i in xrange( 0, len(colors), 4 ): state = colors[ i ] rVal = colors[ i + 1 ] gVal = colors[ i + 2 ] bVal = colors[ i + 3 ] palette[ state ] = ( rVal, gVal, bVal ) return palette def main( step = 1, start = 0 ): global bound, expand, duration # get selection and set to boundary bound = g.getselrect() if duration == None: duration = int( g.getgen() ) if isReset: g.reset() if len( bound ) == 0: g.note( "No selection." ) g.exit() # get current Golly states bound[ 0 ] -= expand bound[ 1 ] -= expand bound[ 2 ] += expand * 2 bound[ 3 ] += expand * 2 left = bound[ 0 ] top = bound[ 1 ] width = bound[ 2 ] height = bound[ 3 ] palette = getPalette() cells = g.getcells( bound ) isMultiStates = len(cells) % 2 == 1 cellW = 3 if isMultiStates else 2 # create image and destination directory dstDir = "%s/%s" % (exportDir, name) if not os.path.exists( dstDir ): os.makedirs( dstDir ) # else: # g.note( "destination folder already exists" ) # g.exit() # log( cells ) for i in xrange( duration ): g.show( "Processing... %d / %d" % (i+1, duration) ) g.run( 1 ) g.update() cells = g.getcells( bound ) # create image img = Image.new( "RGB", ( width, height ) ) cellLen = int( floor( len(cells)/cellW ) * cellW ) for i in xrange( 0, cellLen, cellW ): x = cells[ i ] y = cells[ i + 1 ] state = cells[ i + 2 ] if isMultiStates else 1 img.putpixel( (x-left, y-top), palette[state] ) # save gen = int( g.getgen() ) img.save( "%s/%s_%08d.png" % (dstDir, name, gen) ) #--------------------------------------------- # main main() ================================================ FILE: golly/last-shiki.py ================================================ from __future__ import division import golly as g from PIL import Image from math import floor, ceil, log import os import json import datetime import locale #--------------------------------------------- # settings srcPath = "/Volumes/MugiRAID1/Works/2015/13_0xff/ae/shiki_3.tif" dstDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/last-shiki" expand = 100 repeat = 20 interval = 3 #--------------------------------------------- # settings def log( data ): g.note( json.dumps(data) ) def main( step = 1, start = 0 ): # set dir name from current date d = datetime.datetime.today() dirName = "shiki_%02d-%02d-%02d-%02d" % (d.day, d.hour, d.minute, d.second) # create directory exportDir = "%s/%s" % (dstDir, dirName) if not os.path.exists( exportDir ): os.makedirs( exportDir ) # get bound size = getImageSize( srcPath ) bound = [ -expand, -expand, size[0] + expand * 2, size[1] + expand * 2 ] # loop for f in xrange( repeat ): g.show( "Processing... %d / %d" % (f+1, repeat) ) loadImage( srcPath ) g.run( 1 ) g.update() for i in xrange( interval ): g.run( 1 ) g.update() frame = f * interval + i saveImage( bound, "%s/%s/%s_%06d.png" % (dstDir, dirName, dirName, frame) ) def saveImage( bound, path ): left = bound[0] top = bound[1] width = bound[2] height = bound[3] cellW = 2 # create image img = Image.new( "RGB", ( width, height ) ) cells = g.getcells( bound ) cellLen = len( cells ) white = ( 255, 255, 255 ) for i in xrange( 0, cellLen, 2 ): x = cells[ i ] y = cells[ i + 1 ] img.putpixel( (x-left, y-top), (255, 255, 255) ) # save img.save( path ) def getImageSize( path ): img = Image.open( path ) return img.size def loadImage( path ): img = Image.open( path ) size = img.size c = None state = None for y in xrange( 0, size[1] ): for x in xrange( 0, size[0] ): c = img.getpixel( (x, y) ) if c[0] > 128: g.setcell( x, y, 1 ) #--------------------------------------------- # main main() ================================================ FILE: golly/load-image.py ================================================ from __future__ import division import golly as g from PIL import Image from math import floor, ceil, log import os import json #--------------------------------------------- # settings srcPath = "/Volumes/MugiRAID1/Works/2015/13_0xff/ae/a_frame.png" #--------------------------------------------- # settings def log( data ): g.note( json.dumps(data) ) def main( step = 1, start = 0 ): img = Image.open( srcPath ) size = img.size for y in xrange( 0, size[1] ): for x in xrange( 0, size[0] ): c = img.getpixel( (x, y) ) state = 1 if c[0] > 128 else 0 g.setcell( x, y, state ) #--------------------------------------------- # main main() # 0.7019105 * ( 114.953 * tan( 53.13/ 180 * pi / 2) ) ================================================ FILE: golly/rotate.py ================================================ from __future__ import division import golly as g from PIL import Image from math import floor, ceil, log import os import json #--------------------------------------------- # settings #--------------------------------------------- # settings def log( data ): g.note( json.dumps(data) ) def main(): # get selection and set to boundary bound = g.getselrect() if len( bound ) == 0: g.note( "No selection." ) g.exit() # get current Golly states left = bound[ 0 ] top = bound[ 1 ] width = bound[ 2 ] height = bound[ 3 ] for y in xrange( 0, height ): for x in xrange( 0, width ): state = g.getcell( left + x, top + y ) g.setcell( height - y - 600, x - 600, state ) #--------------------------------------------- # main main() ================================================ FILE: golly/step_generation.py ================================================ from __future__ import division import golly as g def main(): g.run(35328) # def main(): # w = 2048 # # g.select([0, 0, w, w]) # # g.select([-w, -w, w, w]) #--------------------------------------------- # main main() ================================================ FILE: others/ResizeBorder.pbk ================================================ kernel ResizeBorder < namespace : "bk"; vendor : "Baku Hashimoot"; version : 1; > { input image4 src; output pixel4 dst; parameter float width < minValue: 0.0; maxValue: 1.0; defaultValue: 1.0; displayName: "Width"; >; parameter float height < minValue: 0.0; maxValue: 1.0; defaultValue: 1.0; displayName: "Height"; >; parameter float left < minValue: 0.0; maxValue: 100.0; defaultValue: 30.0; displayName: "Border Left"; >; parameter float right < minValue: 0.0; maxValue: 100.0; defaultValue: 30.0; displayName: "Border Right"; >; parameter float top < minValue: 0.0; maxValue: 100.0; defaultValue: 30.0; displayName: "Border Top"; >; parameter float bottom < minValue: 0.0; maxValue: 100.0; defaultValue: 30.0; displayName: "Border Bottom"; >; parameter float2 origin < minValue: float2( 0.0, 0.0 ); maxValue: float2( 1.0, 1.0 ); defaultValue: float2( 0.0, 0.0 ); displayName: "Origin"; >; parameter float2 size < minValue: float2( 0.0, 0.0 ); maxValue: float2( 2048.0, 2048.0 ); defaultValue: float2( 100.0, 100.0 ); displayName: "Input Size"; >; float map( float x, float inMin, float inMax, float outMin, float outMax ) { return ( x - inMin ) * ( outMax - outMin ) / ( inMax - inMin ) + outMin; } float resize( float x, float w, float xi, float xo, float bi, float bo ) { float xm; if ( xo - xi >= bi + bo ) { if ( x < xi + bi ) { xm = x - xi; } else if ( x < xo - bo ) { xm = x - xi; //map( x, xi + bi, xo - bo, bi, w - bo ); } else { xm = w - ( xo - x ); //map( x, xo - bo, xo, w - bo, w ); } } else { if ( x < (xi+xo) / 2.0 ) { xm = x - xi; } else { xm = w - ( xo - x ); } } return xm; } void evaluatePixel() { float2 pos = outCoord(); float2 t = float2( width, height ); float2 rectA = origin * size - origin * size * t; float2 rectB = origin * size + ( float2(1.0, 1.0) - origin ) * size * t; pos.x = resize( pos.x, size.x, rectA.x, rectB.x, left, right ); pos.y = resize( pos.y, size.y, rectA.y, rectB.y, top, bottom ); dst = sampleNearest( src, pos ); } } ================================================ FILE: others/ResizeBorderTrim.pbk ================================================ kernel ResizeBorderTrim < namespace : "bk"; vendor : "Baku Hashimoto"; version : 1; > { input image4 src; output pixel4 dst; parameter float trimTop < minValue: 0.0; maxValue: 2048.0; defaultValue: 0.0; displayName: "Trim Top"; >; parameter float trimRight < minValue: 0.0; maxValue: 2048.0; defaultValue: 0.0; displayName: "Trim Right"; >; parameter float trimBottom < minValue: 0.0; maxValue: 2048.0; defaultValue: 0.0; displayName: "Trim Bottom"; >; parameter float trimLeft < minValue: 0.0; maxValue: 2048.0; defaultValue: 0.0; displayName: "Trim Left"; >; parameter float top < minValue: 0.0; maxValue: 100.0; defaultValue: 30.0; displayName: "Border Top"; >; parameter float right < minValue: 0.0; maxValue: 100.0; defaultValue: 30.0; displayName: "Border Right"; >; parameter float bottom < minValue: 0.0; maxValue: 100.0; defaultValue: 30.0; displayName: "Border Bottom"; >; parameter float left < minValue: 0.0; maxValue: 100.0; defaultValue: 30.0; displayName: "Border Left"; >; parameter float2 origin < minValue: float2( 0.0, 0.0 ); maxValue: float2( 1.0, 1.0 ); defaultValue: float2( 0.0, 0.0 ); displayName: "Origin"; >; parameter float2 size < minValue: float2( 0.0, 0.0 ); maxValue: float2( 2048.0, 2048.0 ); defaultValue: float2( 100.0, 100.0 ); displayName: "Input Size"; >; float map( float x, float inMin, float inMax, float outMin, float outMax ) { return ( x - inMin ) * ( outMax - outMin ) / ( inMax - inMin ) + outMin; } float resize( float x, float w, float xi, float xo, float bi, float bo ) { float xm; if ( xo - xi >= bi + bo ) { if ( x < xi + bi ) { xm = x - xi; } else if ( x < xo - bo ) { xm = x - xi; //map( x, xi + bi, xo - bo, bi, w - bo ); } else { xm = w - ( xo - x ); //map( x, xo - bo, xo, w - bo, w ); } } else { if ( x < (xi+xo) / 2.0 ) { xm = x - xi; } else { xm = w - ( xo - x ); } } return xm; } void evaluatePixel() { float2 pos = outCoord(); float2 rectA = float2( trimLeft, trimTop ); float2 rectB = float2( size.x - trimRight, size.y - trimBottom ); pos.x = resize( pos.x, size.x, rectA.x, rectB.x, left, right ); pos.y = resize( pos.y, size.y, rectA.y, rectB.y, top, bottom ); dst = sampleNearest( src, pos ); } } ================================================ FILE: others/p5.sh ================================================ #!/bin/sh function usage_exit() { echo "Usage: p5 sketch-path [--args sketch-args..]" exit 1 } # get full path of sketch directory if [ "$1" == "" -o "$1" == "--args" ]; then usage_exit fi sketch=$1 absPath=$(cd $(dirname $1) && pwd)/$(basename $1) # extract arguments shift if [ "$1" == "--args" ]; then shift else while [ "$1" != "" ] do shift done fi # run sketch processing-java --sketch=${absPath} --run ${@} ================================================ FILE: p5/cell_division_test/CellDivision.pde ================================================ float gaussianRange = 4; float detail = 0.05; int minGen = 3; PGraphics divideCell( int w, int h, int minWidth ) { ArrayList< Cell > cells = new ArrayList< Cell >(); ArrayList< Cell > divided = new ArrayList< Cell >(); float tx, ty; boolean proceed; int px, py; Cell c; Cell[] nc = new Cell[ 4 ]; PGraphics g = createGraphics( w, h ); cells.add( new Cell( 0, 0, w, h ) ); while ( cells.size() > 0 ) { println( "start" + cells.get(0).generation ); for ( int i = cells.size() - 1; i >= 0; i-- ) { c = cells.get( i ); //c.print(); //println(" -> "); // divide vertical tx = ( c.w / 2 - minWidth ) / gaussianRange; px = int( c.w / 2 + randomGaussian() * tx ); ty = ( c.h / 2 - minWidth ) / gaussianRange; py = int( c.h / 2 + randomGaussian() * ty ); // 0 1 // 2 3 nc[0] = new Cell( c.x, c.y, px, py ); nc[1] = new Cell( c.x + px, c.y, c.w - px, py ); nc[2] = new Cell( c.x, c.y + py, px, c.h - py ); nc[3] = new Cell( c.x + px, c.y + py, c.w - px, c.h - py ); for ( int j = 0; j < nc.length; j++ ) { nc[j].generation = c.generation + 1; if ( nc[j].generation < minGen ) { proceed = true; } else { proceed = random(1) > detail; } if ( nc[j].w >= minWidth * 2 && nc[j].h >= minWidth * 2 && proceed ) { cells.add( nc[j] ); } else { divided.add( nc[j] ); } } cells.remove( i ); } g.beginDraw(); g.background( 0 ); g.noStroke(); for ( int i = 0; i < cells.size(); i++ ) { c = cells.get( i ); g.fill( c.fill ); g.rect( c.x, c.y, c.w, c.h ); } g.endDraw(); image( g, 0, 0 ); } // draw g.beginDraw(); g.background( 0 ); g.noStroke(); for ( int i = 0; i < divided.size(); i++ ) { c = divided.get( i ); g.fill( c.fill ); g.rect( c.x, c.y, c.w, c.h ); } g.endDraw(); return g; } class Cell { int x, y, w, h; color fill; int generation; Cell( int _x, int _y, int _w, int _h ) { this.x = _x; this.y = _y; this.w = _w; this.h = _h; this.fill = color( random(255), random(255), random(255) ); this.generation = 0; } void print() { println( this.x + "\t" + this.y + "\t" + this.w + "\t" + this.h ); } } ================================================ FILE: p5/cell_division_test/cell_division_test.pde ================================================ int w = 100 + 24; void setup() { size( 640, 640 ); PGraphics cell = divideCell( width, height, 10 ); image( cell, 0, 0 ); } ================================================ FILE: p5/cell_division_test/util.pde ================================================ void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } ================================================ FILE: p5/cubist/cubist.pde ================================================ import java.util.Collections; import ffff.*; //--------------------------------------------- // config String srcDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist/src"; String dstDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist/out"; String filename = "cell_a_4"; int duration = 24; int inRand = 2; int moveWidth = 600; float moveAmpOpposite = 0.7; float moveRand = 0.5; //--------------------------------------------- // main PImage src; boolean[][] filled; ArrayList< Rect > rects = new ArrayList< Rect >(); ArrayList< UIRect > uiRects = new ArrayList< UIRect >(); int[] inFrames; Rect[] fromRects, toRects; void setup() { noSmooth(); ArrayList< String > arguments = getArgs(); if ( arguments.size() > 0 ) { filename = arguments.get( 0 ); } src = loadImage( srcDir + "/" + filename + ".png" ); changeWindowSize( src.width, src.height ); filled = new boolean[ width ][ height ]; // initialize fiiled for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { filled[x][y] = src.get( x, y ) == color( 0 ); } } // search searchRect( 1.5, 20 ); searchRect( max( width, height ), 3 ); loadUI(); uiRects = generateUIRects( rects ); // shuffle Collections.shuffle( uiRects ); // calc in frame and determine move rect inFrames = new int[ uiRects.size() ]; fromRects = new Rect[ uiRects.size() ]; toRects = new Rect[ uiRects.size() ]; UIRect ur; for ( int i = 0; i < uiRects.size(); i++ ) { ur = uiRects.get( i ); int dir = int( random( 4 ) ); int mfw = int( 600 * (1 + random( moveRand ) ) ); // move width ( fromt ) int mow = int( mfw * moveAmpOpposite ); // move width ( opposite ) toRects[i] = new Rect( ur.x, ur.y, ur.w, ur.h ); inFrames[i] = int( random( inRand ) ); if ( dir == 0 ) { // N fromRects[i] = new Rect( ur.x, ur.y - mfw, ur.w, ur.h + mfw - mow ); } else if ( dir == 1 ) { // E fromRects[i] = new Rect( ur.x + mow, ur.y, ur.w + mfw - mow, ur.h ); } else if ( dir == 2 ) { // S fromRects[i] = new Rect( ur.x, ur.y + mow, ur.w, ur.h + mfw - mow ); } else if ( dir == 3 ) { // W fromRects[i] = new Rect( ur.x - mfw, ur.y, ur.w + mfw - mow, ur.h ); } } } void draw() { // save Color map if ( frameCount == 1 ) { background( 0 ); noStroke(); for ( int i = 0; i < uiRects.size(); i++ ) { fill( random(255), random(255), random(255) ); rect( uiRects.get( i ).x, uiRects.get( i ).y, uiRects.get( i ).w, uiRects.get( i ).h ); } saveFrame( dstDir + "/" + filename + "/" + filename + "_map.png" ); } background( 0 ); noStroke(); UIRect ur; float t; for ( int i = 0; i < uiRects.size(); i++ ) { ur = uiRects.get( i ); if ( inFrames[i] < frameCount ) { // update t = min( float( frameCount - inFrames[i] - 1) / duration, 1.0 ); t = 1 - t; t = pow( t, 3 ); t = 1 - t; ur.interpolate( t, fromRects[i], toRects[i] ); ur.draw(); } //break; } saveFrame( dstDir + "/" + filename + "/" + filename + "_####.png" ); if ( frameCount > duration + 2 ) { exit(); } } ================================================ FILE: p5/cubist/rect.pde ================================================ void searchRect( float maxAspect, int minWidth ) { for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { if ( !filled[x][y] ) { // start searching Rect r = findRect( x, y ); if ( r.w >= minWidth && r.h >= minWidth && r.aspect() <= maxAspect && 1.0 / r.aspect() <= maxAspect ) { checkSearchedRect( r ); rects.add( r ); } } } } println( "end search: aspect=", maxAspect, "minWidth=", minWidth ); } void checkSearchedRect( Rect r ) { // fill for ( int _y = r.y; _y <= r.bottom(); _y++ ) { for ( int _x = r.x; _x <= r.right(); _x++ ) { filled[_x][_y] = true; } } } Rect findRect( int x, int y ) { Rect r = new Rect( x, y, 1, 1 ); Rect outer = new Rect(); // expand top /*outer.copy( r ); do { outer.y -= 1; outer.h += 2; if ( searchRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true );*/ // expand right outer.copy( r ); do { outer.w += 1; if ( searchRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true ); // expand bottom outer.copy( r ); do { outer.h += 1; if ( searchRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true ); /*// expand left outer.copy( r ); do { outer.x -= 1; outer.w += 2; if ( searchRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true );*/ return r; } boolean searchRectEdge( Rect r ) { if ( r.x < 0 || r.y < 0 || r.right() >= width || r.bottom() >= height ) { return false; } // horizontal edge for ( int x = r.x; x <= r.right(); x++ ) { if ( filled[x][r.y] || filled[x][r.bottom()] ) { return false; } } // vertical edge for ( int y = r.y; y <= r.bottom(); y++ ) { if( filled[r.x][y] || filled[r.right()][y] ) { return false; } } return true; } ================================================ FILE: p5/cubist/ui.pde ================================================ String partsDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist/parts"; ArrayList< UI > uiList = new ArrayList< UI >(); void loadUI() { // smaller --> bigger uiList.add( new UI( partsDir+"/dot.png", 1, 1, 1, 1 ) ); uiList.add( new UI( partsDir+"/button.png", 2, 2, 2, 2 ) ); uiList.add( new UI( partsDir+"/icon.png", 6, 6, 24, 6 ) ); uiList.add( new UI( partsDir+"/menu.png", 19, 2, 1, 19 ) ); uiList.add( new UI( partsDir+"/button_b.png", 8, 8, 8, 8 ) ); uiList.add( new UI( partsDir+"/window_a.png", 31, 54, 31, 31 ) ); } ArrayList< UIRect > generateUIRects( ArrayList< Rect > rects ) { Rect r; UI ui= new UI(); ArrayList< UIRect > uiRects = new ArrayList< UIRect >(); for ( int i = 0; i < rects.size(); i++ ) { r = rects.get( i ); for ( int j = 0; j < uiList.size(); j++ ) { if ( !uiList.get( j ).isSupport( r ) ) { break; } ui = uiList.get( j ); } uiRects.add( new UIRect( ui, r ) ); } return uiRects; } class UI { PImage uiTopLeft, uiTopRight, uiBottomLeft, uiBottomRight, uiTop, uiRight, uiBottom, uiLeft, uiCenter; int top, right, bottom, left; String name; UI() { } UI( String path, int top, int right, int bottom, int left ) { this.top = top; this.right = right; this.bottom = bottom; this.left = left; PImage img = loadImage( path ); int w = img.width, h = img.height; uiTopLeft = decomposeToUIPart( img, 0, 0, left, top ); uiTopRight = decomposeToUIPart( img, w - right, 0, right, top ); uiBottomLeft = decomposeToUIPart( img, 0, h - bottom, left, bottom ); uiBottomRight = decomposeToUIPart( img, w - right, h - bottom, right, bottom ); uiTop = decomposeToUIPart( img, left, 0, w - left - right, top ); uiBottom = decomposeToUIPart( img, left, h - bottom, w - left - right, bottom ); uiLeft = decomposeToUIPart( img, 0, top, left, h - top - bottom ); uiRight = decomposeToUIPart( img, w - right, top, right, h - top - bottom ); uiCenter = decomposeToUIPart( img, left, top, w - left - right, h - top - bottom ); } boolean isSupport( Rect r ) { return r.w >= left + right + 1 && r.h >= top + bottom + 1; } void drawToGraphics( PGraphics pg, Rect r ) { int et = r.y + top, er = r.x + r.w - right, eb = r.y + r.h - bottom, el = r.x + left, ew = r.w - left - right, eh = r.h - top - bottom; pg.image( uiTopLeft, r.x, r.y ); pg.image( uiTopRight, er, r.y ); pg.image( uiBottomLeft, r.x, eb ); pg.image( uiBottomRight, er, eb ); pg.image( uiTop, el, r.y, ew, top ); pg.image( uiBottom, el, eb, ew, bottom ); pg.image( uiLeft, r.x, et, left, eh ); pg.image( uiRight, er, et, right, eh ); pg.image( uiCenter, el, et, ew, eh ); } void draw( Rect r ) { int et = r.y + top, er = r.x + r.w - right, eb = r.y + r.h - bottom, el = r.x + left, ew = r.w - left - right, eh = r.h - top - bottom; image( uiTopLeft, r.x, r.y ); image( uiTopRight, er, r.y ); image( uiBottomLeft, r.x, eb ); image( uiBottomRight, er, eb ); image( uiTop, el, r.y, ew, top ); image( uiBottom, el, eb, ew, bottom ); image( uiLeft, r.x, et, left, eh ); image( uiRight, er, et, right, eh ); image( uiCenter, el, et, ew, eh ); } } PImage decomposeToUIPart( PImage img, int x, int y, int w, int h ) { PImage part = createImage( w, h, RGB ); part.copy( img, x, y, w, h, 0, 0, w, h ); return part; } /* color uiGray = color( 204, 206, 204 ), uiWhite = color( 252, 254, 252 ), uiBlack = color( 124, 126, 124 ); PImage renderUI( ArrayList< Rect > rects, int w, int h, int scale ) { PGraphics pg = createGraphics( width * scale, height * scale ); Rect r; pg.beginDraw(); pg.background( 0 ); pg.noStroke(); for ( int i = 0; i < rects.size(); i++ ) { r = rects.get(i); renderBevel( pg, r, scale, 2 ); } pg.endDraw(); return pg.get(); } void renderBevel( PGraphics pg, Rect r, int scale, int w ) { pg.fill( uiGray ); pg.rect( r.x * scale, r.y * scale, r.w * scale, r.h * scale ); pg.fill( uiBlack ); pg.rect( ( r.x + r.w ) * scale - w, r.y * scale, w, r.h * scale ); pg.rect( r.x * scale, ( r.y + r.h ) * scale - w, r.w * scale, w ); pg.fill( uiWhite ); for ( int i = 0; i < w; i++ ) { pg.rect( r.x * scale + i, r.y * scale, 1, r.h * scale - i ); pg.rect( r.x * scale, r.y * scale + i, r.w * scale - i, 1 ); } }*/ ================================================ FILE: p5/cubist/util.pde ================================================ class Rect { int x, y, w, h; Rect() { x = y = w = h = 0; } Rect( int _x, int _y, int _w, int _h ) { x = _x; y = _y; w = _w; h = _h; } void print() { println( x + "\t" + y + "\t" + w + "\t" + h ); } int right() { return x + w - 1; } int bottom() { return y + h - 1; } float aspect() { return float( w ) / float( h ); } void interpolate( float t, Rect a, Rect b ) { x = int( a.x + ( b.x - a.x ) * t ); y = int( a.y + ( b.y - a.y ) * t ); w = int( a.w + ( b.w - a.w ) * t ); h = int( a.h + ( b.h - a.h ) * t ); } void draw() { rect( x, y, w, h ); } void copy( Rect r ) { x = r.x; y = r.y; w = r.w; h = r.h; } } class UIRect extends Rect { UI ui; UIRect( UI ui, Rect r ) { super( r.x, r.y, r.w, r.h ); this.ui = ui; } void draw() { ui.draw( this ); } } ================================================ FILE: p5/cubist_galaxy/cubist_galaxy.pde ================================================ import java.util.Collections; //--------------------------------------------- // config String srcDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist-galaxy/src"; String dstDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist-galaxy/out"; String filename = "cell_h"; int duration = 6; int inRand = 0; int border = 1; //--------------------------------------------- // main PImage src; boolean[][] filled; ArrayList< Rect > rects = new ArrayList< Rect >(); ArrayList< UIRect > uiRects = new ArrayList< UIRect >(); int[] inFrames; Rect[] fromRects, toRects; void setup() { noSmooth(); frameRate(300); ArrayList< String > arguments = getArgs(); if ( arguments.size() > 0 ) { filename = arguments.get( 0 ); } loadAndSearch( srcDir + "/" + filename + ".png" ); //loadAndSearch( srcDir + "/" + filename + "_2.png" ); //loadAndSearch( srcDir + "/" + filename + "_3.png" ); //loadAndSearch( srcDir + "/" + filename + "_4.png" ); loadUI(); uiRects = generateUIRects( rects ); // shuffle Collections.shuffle( uiRects ); // calc in frame and determine move rect fromRects = new Rect[ uiRects.size() ]; toRects = new Rect[ uiRects.size() ]; inFrames = new int[ uiRects.size() ]; UIRect ur; Rect tr; for ( int i = 0; i < uiRects.size(); i++ ) { ur = uiRects.get( i ); int cx = ur.x + int(ur.w / 2); int cy = ur.y + int(ur.h / 2); tr = new Rect(ur.x, ur.y, ur.w, ur.h); tr.w -= border * 2; tr.h -= border * 2; tr.x += border; tr.h += border; toRects[i] = tr; fromRects[i] = new Rect(cx, cy, 0, 0); inFrames[i] = int(random(inRand)); } } void draw() { background( 0 ); noStroke(); UIRect ur; float t; for ( int i = 0; i < uiRects.size(); i++ ) { ur = uiRects.get( i ); if (inFrames[i] < frameCount) { // update t = min( float(frameCount-inFrames[i]-1) / duration, 1.0 ); t = 1 - t; t = pow( t, 1 ); t = 1 - t; ur.interpolate( t, fromRects[i], toRects[i] ); ur.draw(); } //break; } saveFrame( dstDir + "/" + filename + "/" + filename + "_####.png" ); if ( frameCount > duration + inRand + 2 ) { exit(); } } ================================================ FILE: p5/cubist_galaxy/rect.pde ================================================ color[] colors = { color(255, 0, 0), color(0, 255, 0), color(0, 0, 255), color(255, 255, 0) }; void loadAndSearch( String path ) { src = loadImage( path ); changeWindowSize( src.width, src.height ); filled = new boolean[ width ][ height ]; // initialize fiiled for ( int i = 0; i < colors.length; i++ ) { for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { filled[x][y] = src.get( x, y ) != colors[i]; } } // search searchRect( 1.5, 20 ); searchRect( max( width, height ), 3 ); } } void searchRect( float maxAspect, int minWidth ) { for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { if ( !filled[x][y] ) { // start searching Rect r = findRect( x, y ); if ( r.w >= minWidth && r.h >= minWidth && r.aspect() <= maxAspect && 1.0 / r.aspect() <= maxAspect ) { checkSearchedRect( r ); rects.add( r ); } } } } println( "end search: aspect=", maxAspect, "minWidth=", minWidth ); } void checkSearchedRect( Rect r ) { // fill for ( int _y = r.y; _y <= r.bottom(); _y++ ) { for ( int _x = r.x; _x <= r.right(); _x++ ) { filled[_x][_y] = true; } } } Rect findRect( int x, int y ) { Rect r = new Rect( x, y, 1, 1 ); Rect outer = new Rect(); // expand top /*outer.copy( r ); do { outer.y -= 1; outer.h += 2; if ( searchRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true );*/ // expand right outer.copy( r ); do { outer.w += 1; if ( searchRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true ); // expand bottom outer.copy( r ); do { outer.h += 1; if ( searchRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true ); /*// expand left outer.copy( r ); do { outer.x -= 1; outer.w += 2; if ( searchRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true );*/ return r; } boolean searchRectEdge( Rect r ) { if ( r.x < 0 || r.y < 0 || r.right() >= width || r.bottom() >= height ) { return false; } // horizontal edge for ( int x = r.x; x <= r.right(); x++ ) { if ( filled[x][r.y] || filled[x][r.bottom()] ) { return false; } } // vertical edge for ( int y = r.y; y <= r.bottom(); y++ ) { if( filled[r.x][y] || filled[r.right()][y] ) { return false; } } return true; } ================================================ FILE: p5/cubist_galaxy/ui.pde ================================================ import java.util.Collections; import java.util.Comparator; String partsDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist-galaxy/_parts"; ArrayList< UI > uiList = new ArrayList< UI >(); void loadUI() { // smaller --> bigger uiList.add( new UI( partsDir+"/p00.png", 3, 3, 3, 3 ) ); uiList.add( new UI( partsDir+"/p01.png", 2, 2, 2, 2 ) ); uiList.add( new UI( partsDir+"/p02.png", 1, 1, 1, 1 ) ); uiList.add( new UI( partsDir+"/p03.png", 6, 6, 6, 6 ) ); //uiList.add( new UI( partsDir+"/p04.png", 14, 14, 14, 14 ) ); //uiList.add( new UI( partsDir+"/p05.png", 14, 14, 14, 14 ) ); uiList.add( new UI( partsDir+"/p06.png", 8, 9, 8, 8 ) ); uiList.add( new UI( partsDir+"/p07.png", 1, 1, 1, 1 ) ); uiList.add( new UI( partsDir+"/p08.png", 8, 2, 2, 2 ) ); uiList.add( new UI( partsDir+"/p09.png", 8, 2, 2, 6 ) ); uiList.add( new UI( partsDir+"/p10.png", 5, 5, 13, 5 ) ); uiList.add( new UI( partsDir+"/p11.png", 5, 5, 13, 5 ) ); uiList.add( new UI( partsDir+"/p12.png", 6, 6, 6, 6 ) ); uiList.add( new UI( partsDir+"/p13.png", 6, 6, 6, 6 ) ); uiList.add( new UI( partsDir+"/p14.png", 16, 15, 14, 10 ) ); } ArrayList< UIRect > generateUIRects( ArrayList< Rect > rects ) { Rect r; UI ui = new UI(); ArrayList< UIRect > uiRects = new ArrayList< UIRect >(); ArrayList< UI > supported = new ArrayList< UI >(); for ( int i = 0; i < rects.size(); i++ ) { r = rects.get( i ); supported.clear(); for ( int j = 0; j < uiList.size(); j++ ) { if ( uiList.get(j).isSupport(r) ) { supported.add( uiList.get(j) ); } } if ( supported.size() > 0 ) { Collections.sort( supported, new UIComparator() ); Collections.reverse( supported ); int maxIndex = Math.max(1, ceil( supported.size() / 3 ) ); int index = int( random(maxIndex) ); ui = supported.get(index); uiRects.add(new UIRect(ui, r)); } } return uiRects; } class UIComparator implements Comparator< UI > { public int compare(UI ui1, UI ui2) { return ui1.getMinArea() < ui2.getMinArea() ? -1 : 1; } } class UI { PImage uiTopLeft, uiTopRight, uiBottomLeft, uiBottomRight, uiTop, uiRight, uiBottom, uiLeft, uiCenter; int top, right, bottom, left; String name; UI() { } UI( String path, int top, int right, int bottom, int left ) { this.top = top; this.right = right; this.bottom = bottom; this.left = left; PImage img = loadImage( path ); int w = img.width, h = img.height; uiTopLeft = decomposeToUIPart( img, 0, 0, left, top ); uiTopRight = decomposeToUIPart( img, w - right, 0, right, top ); uiBottomLeft = decomposeToUIPart( img, 0, h - bottom, left, bottom ); uiBottomRight = decomposeToUIPart( img, w - right, h - bottom, right, bottom ); uiTop = decomposeToUIPart( img, left, 0, w - left - right, top ); uiBottom = decomposeToUIPart( img, left, h - bottom, w - left - right, bottom ); uiLeft = decomposeToUIPart( img, 0, top, left, h - top - bottom ); uiRight = decomposeToUIPart( img, w - right, top, right, h - top - bottom ); uiCenter = decomposeToUIPart( img, left, top, w - left - right, h - top - bottom ); } boolean isSupport( Rect r ) { return r.w >= left + right && r.h >= top + bottom; } int getMinArea() { return (left + right) * (top + bottom); } void drawToGraphics( PGraphics pg, Rect r ) { int et = r.y + top, er = r.x + r.w - right, eb = r.y + r.h - bottom, el = r.x + left, ew = r.w - left - right, eh = r.h - top - bottom; pg.image( uiTopLeft, r.x, r.y ); pg.image( uiTopRight, er, r.y ); pg.image( uiBottomLeft, r.x, eb ); pg.image( uiBottomRight, er, eb ); pg.image( uiTop, el, r.y, ew, top ); pg.image( uiBottom, el, eb, ew, bottom ); pg.image( uiLeft, r.x, et, left, eh ); pg.image( uiRight, er, et, right, eh ); pg.image( uiCenter, el, et, ew, eh ); } void draw( Rect r ) { int et = r.y + top, er = r.x + r.w - right, eb = r.y + r.h - bottom, el = r.x + left, ew = r.w - left - right, eh = r.h - top - bottom; if ( !isSupport(r) ) { return; } image( uiTopLeft, r.x, r.y ); image( uiTopRight, er, r.y ); image( uiBottomLeft, r.x, eb ); image( uiBottomRight, er, eb ); image( uiTop, el, r.y, ew, top ); image( uiBottom, el, eb, ew, bottom ); image( uiLeft, r.x, et, left, eh ); image( uiRight, er, et, right, eh ); image( uiCenter, el, et, ew, eh ); } } PImage decomposeToUIPart( PImage img, int x, int y, int w, int h ) { PImage part = createImage( w, h, RGB ); part.copy( img, x, y, w, h, 0, 0, w, h ); return part; } /* color uiGray = color( 204, 206, 204 ), uiWhite = color( 252, 254, 252 ), uiBlack = color( 124, 126, 124 ); PImage renderUI( ArrayList< Rect > rects, int w, int h, int scale ) { PGraphics pg = createGraphics( width * scale, height * scale ); Rect r; pg.beginDraw(); pg.background( 0 ); pg.noStroke(); for ( int i = 0; i < rects.size(); i++ ) { r = rects.get(i); renderBevel( pg, r, scale, 2 ); } pg.endDraw(); return pg.get(); } void renderBevel( PGraphics pg, Rect r, int scale, int w ) { pg.fill( uiGray ); pg.rect( r.x * scale, r.y * scale, r.w * scale, r.h * scale ); pg.fill( uiBlack ); pg.rect( ( r.x + r.w ) * scale - w, r.y * scale, w, r.h * scale ); pg.rect( r.x * scale, ( r.y + r.h ) * scale - w, r.w * scale, w ); pg.fill( uiWhite ); for ( int i = 0; i < w; i++ ) { pg.rect( r.x * scale + i, r.y * scale, 1, r.h * scale - i ); pg.rect( r.x * scale, r.y * scale + i, r.w * scale - i, 1 ); } }*/ ================================================ FILE: p5/cubist_galaxy/util.pde ================================================ void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } ArrayList< String > getArgs() { ArrayList< String > arguments = new ArrayList< String >(); try { for ( int i = 0; i < args.length; i++ ) { arguments.add( args[i] ); } } catch ( Exception e ) { return arguments; } return arguments; } String getFileName( String path ) { String filename = new File( path ).getName(); int point = filename.lastIndexOf("."); if (point != -1) { return filename.substring(0, point); } return filename; } String getDirectory( String path ) { return new File( path ).getParent(); } class Rect { int x, y, w, h; Rect() { x = y = w = h = 0; } Rect( int _x, int _y, int _w, int _h ) { x = _x; y = _y; w = _w; h = _h; } void print() { println( x + "\t" + y + "\t" + w + "\t" + h ); } int right() { return x + w - 1; } int bottom() { return y + h - 1; } float aspect() { return float( w ) / float( h ); } void interpolate( float t, Rect a, Rect b ) { x = int( a.x + ( b.x - a.x ) * t ); y = int( a.y + ( b.y - a.y ) * t ); w = int( a.w + ( b.w - a.w ) * t ); h = int( a.h + ( b.h - a.h ) * t ); } void draw() { rect( x, y, w, h ); } void copy( Rect r ) { x = r.x; y = r.y; w = r.w; h = r.h; } } class UIRect extends Rect { UI ui; UIRect( UI ui, Rect r ) { super( r.x, r.y, r.w, r.h ); this.ui = ui; } void draw() { ui.draw( this ); } } ================================================ FILE: p5/dla/Particle.pde ================================================ // --------------- // Particle.pde // --------------- // neighbor int nlen = 8; int[] nx = { 0, +1, +1, +1, 0, -1, -1, -1 }; int[] ny = { -1, -1, 0, +1, +1, +1, 0, -1 }; // weight float weight; float weightRandom = 5.8; float[] weightBk = new float[ nlen ]; class Particle { int x, y; boolean isSeed = false; boolean stuck = false; boolean isOut = false; Particle( int threshold ) { reset( threshold ); } void reset( int threshold ) { // keep choosing random spots until an empty one is found do { x = floor( random(width) );//floor( random(width/2) ) * 2; y = floor( random(height) );//floor( random(height/2) ) * 2; } while (field[y * width + x] || (weightMap.get( x, y ) & 0xff) < threshold ); } void update() { // move around if (!stuck) { // read weight //weightSum = 0; /*for ( int i = 0; i < nlen; i++ ) { weightSum += pow( float( map.get( x + nx[i], y + ny[i] ) & 0xff ), 3 ); weightBk[ i ] = weightSum; //print( weightSum + "\t" ); } r = random( weightSum ); //println( "|" + r ); for ( int i = 0; i < nlen; i++ ) { if ( r <= weightBk[i] ) { x += nx[i]; y += ny[i]; break; } }*/ float maxWeight = -weightRandom * 2; int maxDir = 0; for ( int i = 0; i < nlen; i++ ) { weight = float( weightMap.get( x + nx[i], y + ny[i] ) & 0xff ) / 255.0 + random( -weightRandom, weightRandom ); if ( weight > maxWeight ) { maxDir = i; maxWeight = weight; } } x += nx[ maxDir ]; y += ny[ maxDir ]; /*x += round(random(-1, 1)); y += round(random(-1, 1));*/ /*if ( random(1) < 0.1 ) { if ( x > width / 2 ) x -= 1; else x += 1; if ( y > height / 2 ) y -= 1; else y += 1; } else { x += round(random(-1, 1)); y += round(random(-1, 1)); }*/ // diagonal random walk //r = int( random( 0, 4 ) ); //if ( r == 0 ) { // x += 1; y -= 1; //} else if ( r == 1 ) { // x += 1; y += 1; //} else if ( r == 2 ) { // x -= 1; y += 1; //} else if ( r == 3 ) { // x -= 1; y -= 1; //} isOut = false; if ( x < 0 ) { x = 0; isOut = true; } if ( y < 0 ) { y = 0; isOut = true; } if ( x >= width ) { x = width - 1; isOut = true; } if ( y >= height ) { y = height - 1; isOut = true; } if ( isOut ) { return; } // test if something is next to us if ( !alone() ) { stuck = true; field[y * width + x] = true; } } } // returns true if no neighboring pixels boolean alone() { int cx = x; int cy = y; // get positions int lx = cx-1; int rx = cx+1; int ty = cy-1; int by = cy+1; // if bound if (cx <= 0 || cx >= width || lx <= 0 || lx >= width || rx <= 0 || rx >= width || cy <= 0 || cy >= height || ty <= 0 || ty >= height || by <= 0 || by >= height) return true; // pre multiply the ys cy *= width; by *= width; ty *= width; // N, W, E, S int neumann = ( field[cx + ty] ? 1 : 0 ) + ( field[lx + cy] ? 1 : 0 ) + ( field[rx + cy] ? 1 : 0 ) + ( field[cx + by] ? 1 : 0 ); /*boolean corner = field[lx + ty] || field[lx + by] || field[rx + ty] || field[rx + by];*/ if ( neumann == 1 ) { return false; } return true; } } ================================================ FILE: p5/dla/Point.pde ================================================ class Point { int x, y; Point( int _x, int _y ) { x = _x; y = _y; } int index() { return x + y * width; } } ================================================ FILE: p5/dla/dla.pde ================================================ //--------------------------------------------- // config String weightMapPath = "../_dat/dla-weight-map.png"; String destDir = "out"; String filename = "dla_neumann_cell_large"; int particleCount = 10000; //--------------------------------------------- // main PImage weightMap; int exportedCount = 0; ArrayList< Particle > particles = new ArrayList< Particle >(); boolean[] field; Point seed; void setup() { size(10, 10, P2D); noSmooth(); weightMap = loadImage(weightMapPath); changeWindowSize( weightMap.width, weightMap.height ); File[] existsImages = listImageFiles(destDir); exportedCount = existsImages.length - 1; println( exportedCount ); // create an array that stores the position of our particles field = new boolean[width * height]; // make particles for(int i=0; i < particleCount; i++) { particles.add( new Particle( 10 ) ); } // make seed for ( int i = 0; i < 40; i++ ) { Particle seed = new Particle( 220 ); seed.isSeed = true; seed.stuck = true; particles.add( seed ); field[seed.x + seed.y * width] = true; } } void draw() { // udapte dla background( 0 ); noFill(); noStroke(); Particle p; for(int i = 0, l = particles.size(); i < l; i++) { p = particles.get( i ); p.update(); if ( p.stuck ) { if ( p.isSeed ) { fill( 255, 255, 0 ); } else { fill( 255, 0, 0 ); } } else { fill( 0, 0, 255 ); } rect( p.x, p.y, 1, 1 ); } } void keyPressed() { String path = destDir + "/" + filename + "/" + filename + "_" + String.format( "%04d", exportedCount++ ) + ".png"; println( "saved: " + path ); saveFrame( path ); } ================================================ FILE: p5/dla/util.pde ================================================ import java.io.FilenameFilter; void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } File[] listImageFiles(String path) { File file = new File(resolveRelativePath(path)); if (file.isDirectory()) { FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String name) { String ext = ""; int dotIndex = name.lastIndexOf('.'); if ((dotIndex > 0) && (dotIndex < name.length() - 1 )) { ext = name.substring(dotIndex + 1).toLowerCase(); } return (ext.equals("png")); } }; return file.listFiles(filter); } else { // If it's not a directory return new File[0]; } } String resolveRelativePath(String path) { File file = new File(sketchPath("") + path); try { return file.getCanonicalPath(); } catch (Exception e) { return null; } } ================================================ FILE: p5/dla_animate/dla_animate.pde ================================================ import processing.video.*; //--------------------------------------------- // config String mapDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/dla-net"; String dstDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/root"; String filename = "root"; boolean isSave = true; //--------------------------------------------- // main PImage map, field, buff; ArrayList< Point > frontier = new ArrayList< Point >(); color colorSeed = color( 255, 255, 0 ); color colorRoot = color( 255, 0, 0 ); color colorFrontier = color( 0, 255, 255 ); color colorReproduced = color( 0, 0, 255 ); int nlen = 4; int[] nx = { 0, +1, 0, -1 }; int[] ny = { -1, 0, +1, 0 }; // 8 //int nlen = 8; //int[] nx = { 0, +1, +1, +1, 0, -1, -1, -1 }; //int[] ny = { -1, -1, 0, +1, +1, +1, 0, -1 }; void setup() { noSmooth(); frameRate( 24 ); map = loadImage( mapDir + "/" + filename + ".png" ); changeWindowSize( map.width, map.height ); field = createImage( width, height, RGB ); buff = createImage( width, height, RGB ); PImage uiImg = subdivideToUI(); uiImg.save( dstDir + "/" + filename + "_ui.png" ); // search seed color c; int x, y; for ( y = 0; y < height; y++ ) { for ( x = 0; x < width; x++ ) { c = map.get( x, y ); if ( c == colorSeed ) { field.set( x, y, colorFrontier ); } if ( c == colorRoot ) { field.set( x, y, colorRoot ); } } } //exit(); } void draw() { if ( frameCount == 1 && isSave ) { image( field, 0, 0 ); saveFrame( dstDir + "/" + filename + "/" + filename + "_0000" ); } // update int x, y, frontierCount = 0; color c; buff.copy( field, 0, 0, width, height, 0, 0, width, height ); for ( y = 0; y < height; y++ ) { for ( x = 0; x < width; x++ ) { c = buff.get( x, y ); if ( c == colorFrontier ) { for ( int i = 0; i < nlen; i++ ) { if( field.get( x + nx[i], y + ny[i] ) == colorRoot ) { field.set( x + nx[i], y + ny[i], colorFrontier ); frontierCount++; } } field.set( x, y, colorReproduced ); } } } background( 0 ); // draw current image and save image( field, 0, 0 ); // and save if ( isSave ) { saveFrame( dstDir + "/" + filename + "/" + filename + "_####" ); } if ( frontierCount == 0 ) { exit(); } } class Point { int x, y; Point( int _x, int _y ) { x = _x; y = _y; } int index() { return x + y * width; } int neighbor( int _x, int _y ) { int nx = x + _x, ny = x + _y; if ( nx < 0 || nx >= width || ny < 0 || ny >= height ) { return -1; } return ny * width + nx; } } ================================================ FILE: p5/dla_animate/ui.pde ================================================ color uiGray = color( 204, 206, 204 ), uiWhite = color( 252, 254, 252 ), uiBlack = color( 124, 126, 124 ); PImage renderUI( ArrayList< Rect > rects, int w, int h, int scale ) { PGraphics pg = createGraphics( width * scale, height * scale ); Rect r; pg.beginDraw(); pg.background( 0 ); pg.noStroke(); for ( int i = 0; i < rects.size(); i++ ) { r = rects.get(i); renderBevel( pg, r, scale, 2 ); } pg.endDraw(); return pg.get(); } void renderBevel( PGraphics pg, Rect r, int scale, int w ) { pg.fill( uiGray ); pg.rect( r.x * scale, r.y * scale, r.w * scale, r.h * scale ); pg.fill( uiBlack ); pg.rect( ( r.x + r.w ) * scale - w, r.y * scale, w, r.h * scale ); pg.rect( r.x * scale, ( r.y + r.h ) * scale - w, r.w * scale, w ); pg.fill( uiWhite ); for ( int i = 0; i < w; i++ ) { pg.rect( r.x * scale + i, r.y * scale, 1, r.h * scale - i ); pg.rect( r.x * scale, r.y * scale + i, r.w * scale - i, 1 ); } } ================================================ FILE: p5/dla_animate/util.pde ================================================ void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } PImage subdivideToUI() { // find frontier ArrayList< Point > search = new ArrayList< Point >(); ArrayList< Rect > rects = new ArrayList< Rect >(); PImage img = createImage( width, height, RGB ); img.copy( map, 0, 0, width, height, 0, 0, width, height ); for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { if ( img.get( x, y ) == colorSeed ) { if( img.get( x, y-1 ) == colorRoot ) search.add( new Point( x, y-1 ) ); if( img.get( x+1, y ) == colorRoot ) search.add( new Point( x+1, y ) ); if( img.get( x, y+1 ) == colorRoot ) search.add( new Point( x, y+1 ) ); if( img.get( x-1, y ) == colorRoot ) search.add( new Point( x-1, y ) ); Rect r = new Rect( x, y, 1, 1 ); rects.add( r ); deleteRoot( img, r ); } } } do { // search rect Point p; int x, y; int x0, y0, x1, y1; boolean hasVertical, hasHorizontal; for ( int i = search.size() - 1; i >= 0; i-- ) { p = search.get( i ); x = p.x; y = p.y; hasHorizontal = img.get( x-1, y ) == colorRoot || img.get( x+1, y ) == colorRoot; hasVertical = img.get( x, y-1 ) == colorRoot || img.get( x, y+1 ) == colorRoot; if ( hasHorizontal && hasVertical ) { if ( random(1) > 0.5 ) { hasHorizontal = false; } else { hasVertical = false; } } // search if ( hasHorizontal ) { x0 = searchDir( search, img, p, -1, 0 ).x; x1 = searchDir( search, img, p, +1, 0 ).x; y0 = y; y1 = y; } else { x0 = x; x1 = x; y0 = searchDir( search, img, p, 0, -1 ).y; y1 = searchDir( search, img, p, 0, +1 ).y; } Rect r = new Rect( x0, y0, x1-x0+1, y1-y0+1 ); rects.add( r ); deleteRoot( img, r ); search.remove( i ); for ( int ry = r.y; ry < r.y + r.h; ry++ ) { for ( int rx = r.x; rx < r.x + r.w; rx++ ) { if( img.get( rx, ry-1 ) == colorRoot ) search.add( new Point( rx, ry-1 ) ); if( img.get( rx+1, ry ) == colorRoot ) search.add( new Point( rx+1, ry ) ); if( img.get( rx, ry+1 ) == colorRoot ) search.add( new Point( rx, ry+1 ) ); if( img.get( rx-1, ry ) == colorRoot ) search.add( new Point( rx-1, ry ) ); } } } } while( search.size() > 0 ); // draw return renderUI( rects, width, height, 8 ); } Point searchDir( ArrayList< Point > search, PImage img, Point origin, int dx, int dy ) { int x = origin.x, y = origin.y; while ( img.get( x+dx, y+dy ) == colorRoot ) { x += dx; y += dy; } return new Point( x, y ); } void deleteRoot( PImage img, Rect r ) { for ( int y = r.y; y < r.y + r.h; y++ ) { for ( int x = r.x; x < r.x + r.w; x++ ) { img.set( x, y, color( 0 ) ); } } } class Rect { int x, y, w, h; Rect( int _x, int _y, int _w, int _h ) { x = _x; y = _y; w = _w; h = _h; } void print() { println( x + "\t" + y + "\t" + w + "\t" + h ); } } ================================================ FILE: p5/filling/filling.pde ================================================ //---------------------------------------- // config String srcDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/filling/_src/"; String destDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/filling"; String filename = "squares_qr_for_filling"; int duration = 15; int startRand = 3; int minLen = 10; //---------------------------------------- // main int[][] dirs; //int N = 0b1, // E = 0b10, // S = 0b100, // W = 0b1000, // X = 0b10000, // undefined // V = 0b100000; // empty PImage shape; int IE = 0, IS = 1, IW = 2, IN = 3; int E = 0b1, S = 0b10, W = 0b100, N = 0b1000; boolean[][] filled; int[] dx = { +1, 0, -1, 0 }; int[] dy = { 0, +1, 0, -1 }; ArrayList< Chain > chain; ArrayList< Frontier > frontier = new ArrayList< Frontier >(); void setup() { shape = loadImage( srcDir + "/" + filename + ".png" ); changeWindowSize( shape.width, shape.height ); filled = new boolean[ shape.width ][ shape.height ]; for ( int y = 0; y < shape.height; y++ ) { for ( int x = 0; x < shape.width; x++ ) { filled[x][y] = shape.get( x, y ) == color( 0 ); } } chain = new ArrayList< Chain >(); int x = 0, y = 0, dir = 0, d = 0; while ( true ) { // find start point outerloop: for ( y = 0; y < shape.height; y++ ) { for ( x = 0; x < shape.width; x++ ) { if ( !filled[x][y] ) break outerloop; } } if ( x == shape.width || y == shape.width ) break; dir = IE; chain.add( new Chain( x, y, true ) ); filled[x][y] = true; while( true ) { for ( int i = 0; i < 4; i++ ) { d = (dir + 3 + i ) % 4; if ( !isFilled( x + dx[d], y + dy[d] ) ) break; } if ( (d+2) % 4 == dir ) { // dead end break; } dir = d; x += dx[ dir ]; y += dy[ dir ]; chain.add( new Chain( x, y, false ) ); filled[x][y] = true; } } int i = 0; while ( i < chain.size() ) { Frontier f = new Frontier(); f.start = i; f.inTime = int( random( 1, startRand+1 ) ); f.end = i + duration - f.inTime - 1; if ( f.end >= chain.size() ) { f.end = chain.size() - 1; } for ( int j = i+1; j < f.end; j++ ) { if ( chain.get(j).begin ) { f.end = j - 1; } } f.setRange(); frontier.add( f ); i = f.end + 1; } passed = new boolean[ shape.width ][ shape.height ]; for (y = 0; y < shape.height; y++ ) { for ( x = 0; x < shape.width; x++ ) { passed[x][y] = false; } } noStroke(); background( 0 ); } boolean[][] passed; void draw() { for ( int y = 0; y < shape.height; y++ ) { for ( int x = 0; x < shape.width; x++ ) { if ( passed[x][y] ) { fill( 0, 0, 255 ); rect( x, y, 1, 1 ); } } } Frontier f; Chain c; if ( frameCount > 1 ) { for ( int i = frontier.size() - 1; i >= 0; i-- ) { f = frontier.get( i ); c = chain.get( f.index ); if ( frameCount - 1 >= f.inTime ) { fill( 255, 0, 0 ); rect( c.x, c.y, 1, 1 ); } c.passed = true; passed[ c.x ][ c.y ] = true; } } for ( int i = frontier.size() - 1; i >= 0; i-- ) { f = frontier.get( i ); c = chain.get( f.index ); if ( frameCount - 1 >= f.inTime ) { if ( !f.next() ) { frontier.remove( i ); } } } saveFrame( destDir + "/filling_" + filename + "/filling_" + filename + "_####.png" ); if (frameCount == duration + 2 ) { println( "end", frameCount ); exit(); } } boolean isFilled( int x, int y ) { if ( x < 0 || y < 0 || x >= shape.width || y >= shape.height ) return true; return filled[x][y]; } class Frontier { int index, dir, inTime, start, end; void setRange() { dir = int(random(2)) * 2 - 1; if ( dir == 1 ) { index = start; } else { index = end; } } boolean next() { index += dir; return start <= index && index <= end; } } class Chain { int x, y; boolean begin; boolean passed = false; Chain( int _x, int _y, boolean _begin ) { x = _x; y = _y; begin = _begin; } } ================================================ FILE: p5/filling/util.pde ================================================ void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } ================================================ FILE: p5/life_like/ca.pde ================================================ boolean[] survive, birth; //------------------------------------------------------- // rules // conway's game of life int[] birthNum = { 3 }; int[] surviveNum = { 2, 3 }; //// replicator //int[] birthNum = { 1, 3, 5, 7 }; //int[] surviveNum = { 1, 3, 5, 7 }; // small-replicator //int[] birthNum = { 2, 5 }; //int[] surviveNum = { 4 }; // 34 Life //int[] birthNum = { 3, 4 }; //int[] surviveNum = { 3, 4 }; // 2x2 //int[] birthNum = { 3, 6 }; //int[] surviveNum = { 1, 2, 5 }; // day and night //int[] birthNum = {3, 6, 7, 8 }; //int[] surviveNum = { 3, 4, 6, 7, 8 }; // HighLife //int[] birthNum = {3, 6}; //int[] surviveNum = { , 3}; // Morley //int[] birthNum = {3, 6, 8}; //int[] surviveNum = {2, 4, 5}; // Diamoeba //int[] birthNum = {3, 5, 6, 7, 8}; //int[] surviveNum = {5, 6, 7, 8}; // explosive one //int[] birthNum = {1, 7}; //int[] surviveNum = {7, 8}; // explosive two //int[] birthNum = {1, 4, 5}; //int[] surviveNum = {3, 4}; // gnarl //int[] birthNum = {1}; //int[] surviveNum = {1}; //// coagulations //int[] birthNum = {3, 7, 8}; //int[] surviveNum = {2, 3, 4, 5, 6, 7, 8}; //// mazectric //int[] birthNum = {3}; //int[] surviveNum = {1, 2, 3, 4, 5}; // amoeba //int[] birthNum = {1, 3, 5, 8}; //int[] surviveNum = {3, 5, 7}; // Serviettes //int[] birthNum = {2, 3, 4}; //int[] surviveNum = {}; //------------------------------------------------------- // class & methods class LifeLikeCA { PImage field, buff; int fw, fh; LifeLikeCA(PImage initCond) { fw = initCond.width; fh = initCond.height; field = initCond; buff = createImage(fw, fh, RGB); } void draw(int x, int y) { image(field, x, y); } void update() { int aliveNum; color next; buff.copy(field, 0, 0, fw, fh, 0, 0, fw, fh); for (int y = 0; y < fh; y++) { for (int x = 0; x < fw; x++) { aliveNum = getAliveCount(buff, x, y); next = colorDead; if (buff.get(x, y) == colorAlive) { if (survive[aliveNum]) { next = colorAlive; } } else { if (birth[aliveNum]) { next = colorAlive; } } field.set(x, y, next); } } } } void setupLifeLikeRules() { // init rules survive = new boolean[9]; birth = new boolean[9]; for (int i = 0; i < 8; i++) { survive[i] = false; birth[i] = false; } for (int i = 0; i < surviveNum.length; i++) { survive[surviveNum[i]] = true; } for (int i = 0; i < birthNum.length; i++) { birth[birthNum[i]] = true; } } int getAliveCount(PImage field, int x, int y) { int neighbors = 0; neighbors += getStatus(field, x, y-1); neighbors += getStatus(field, x+1, y-1); neighbors += getStatus(field, x+1, y); neighbors += getStatus(field, x+1, y+1); neighbors += getStatus(field, x, y+1); neighbors += getStatus(field, x-1, y+1); neighbors += getStatus(field, x-1, y); neighbors += getStatus(field, x-1, y-1); return neighbors; } int getStatus(PImage field, int x, int y) { if (x < 0 || field.width <= x || y < 0 || field.height <= y) { return 0; } else { return field.get(x, y) != colorDead ? 1 : 0; } } ================================================ FILE: p5/life_like/life_like.pde ================================================ //------------------------------------------------------- // config final color colorAlive = color( 255 ); final color colorDead = color( 0 ); final String dstName = "out/####.png"; final String srcName = "../_dat/init-cond.png"; final boolean isSave = true; final int scale = 1; //------------------------------------------------------- // main LifeLikeCA ca; void setup() { // init ca PImage initCond = loadImage( srcName ); setupLifeLikeRules(); ca = new LifeLikeCA( initCond ); // setup noSmooth(); changeWindowSize( initCond.width * scale, initCond.height * scale ); } void draw() { background( 0 ); resetMatrix(); scale( scale ); ca.draw( 0, 0 ); ca.update(); if ( isSave ) { saveFrame( dstName ); } } ================================================ FILE: p5/life_like/util.pde ================================================ void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } ================================================ FILE: p5/life_like_transition/ca.pde ================================================ final color colorAlive = color( 200 ); final color colorDead = color( 100 ); final color colorSeed = color( 255, 0, 0 ); final color colorEmpty= color( 0 ); final color colorWall = color( 0, 255, 0 ); final color colorTemp = color( 0, 0, 255 ); class LifeLikeCA { //PImage field, buff; boolean[][] field, buff; boolean[][] space, seed, wall, temp; boolean[] birth = new boolean[ 9 ], survive = new boolean[ 9 ]; int[][] neighborsOffset = { { 0, -1 }, { +1, -1 }, { +1, 0 }, { +1, +1 }, { 0, +1 }, { -1, +1 }, { -1, 0 }, { -1, -1 } }; int fw, fh; int spaceCount; int gen = 0; LifeLikeCA( PImage _initCond, int[] _birthCond, int[] _surviveCond ) { fw = _initCond.width; fh = _initCond.height; // init field field = new boolean[ fw ][ fh ]; buff = new boolean[ fw ][ fh ]; space = new boolean[ fw ][ fh ]; seed = new boolean[ fw ][ fh ]; wall = new boolean[ fw ][ fh ]; temp = new boolean[ fw ][ fh ]; color c; for ( int y = 0; y < fh; y++ ) { for ( int x = 0; x < fw; x++ ) { c = _initCond.get( x, y ); field[ x ][ y ] = c == colorSeed ? random(1) <= rate : false; // init attr space[x][y] = c != colorEmpty; seed[ x ][ y ] = c == colorSeed; wall[ x ][ y ] = c == colorWall; temp[ x ][ y ] = c == colorTemp; if ( x == 5 && y == 3 ) { println( seed[x][y] ); println( red(c), green(c), blue(c) ); } } } // init rules for ( int i = 0; i < 8; i++ ) { survive[i] = false; birth[i] = false; } for ( int i = 0; i < _surviveCond.length; i++ ) { survive[ _surviveCond[i] ] = true; } for ( int i = 0; i < _birthCond.length; i++ ) { birth[ _birthCond[i] ] = true; } } void clear() { for ( int y = 0; y < fh; y++ ) { for ( int x = 0; x < fw; x++ ) { field[ x ][ y ] = false; } } } void updateSeed( PImage seedImg ) { //int seedCount = 0; color c; for ( int y = 0; y < fh; y++ ) { for ( int x = 0; x < fw; x++ ) { c = seedImg.get( x, y ); seed[ x ][ y ] = c == colorSeed; field[ x ][ y ] |= c == colorSeed; } } } void draw() { int x, y; noStroke(); for ( y = 0; y < fh; y++ ) { for ( x = 0; x < fw; x++ ) { fill( field[ x ][ y ] ? colorAlive : colorDead ); rect( x, y, 1, 1 ); } } } void save( String name ) { //field.save( name ); } int width() { return fw; } int height() { return fh; } void update() { int x, y; int alives; for ( y = 0; y < fh; y++ ) { for (x = 0; x < fw; x++ ) { buff[ x ][ y ] = field[ x ][ y ]; } } for ( y = 0; y < fh; y++ ) { for ( x = 0; x < fw; x++ ) { if ( space[ x ][ y ] ) { if ( wall[ x ][ y ] ) { wall[ x ][ y ] = !canDestroyWall( x, y ); } else { alives = getAliveCount( x, y ); field[ x ][ y ] = buff[ x ][ y ] ? survive[ alives ] : birth[ alives ]; } } } } gen++; } boolean canDestroyWall( int x, int y ) { int ox, oy; for ( int i = 0; i < neighborsOffset.length; i++ ) { ox = x + neighborsOffset[i][0]; oy = y + neighborsOffset[i][1]; if ( ox < 0 || fw <= ox || oy < 0 || fh <= oy ) { continue; } if ( !seed[ ox ][ oy ] && buff[ ox ][ oy ] ) { return true; } } return false; } int getAliveCount( int x, int y ) { int neighbors = 0; neighbors += getStatus( x , y-1 ) ? 1 : 0; neighbors += getStatus( x+1, y-1 ) ? 1 : 0; neighbors += getStatus( x+1, y ) ? 1 : 0; neighbors += getStatus( x+1, y+1 ) ? 1 : 0; neighbors += getStatus( x , y+1 ) ? 1 : 0; neighbors += getStatus( x-1, y+1 ) ? 1 : 0; neighbors += getStatus( x-1, y ) ? 1 : 0; neighbors += getStatus( x-1, y-1 ) ? 1 : 0; return neighbors; } boolean getStatus( int x, int y ) { if ( x < 0 || fw <= x || y < 0 || fh <= y ) { return false; } else { return buff[ x ][ y ]; } } } ================================================ FILE: p5/life_like_transition/life_like_transition.pde ================================================ //------------------------------------------------------- // config final String srcDir = "../../ca/life-like-generation/_src"; final String dstDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/life-like-generation"; final String seedDir= "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/life-like-generation/_seed"; final boolean isSave = true; final int scale = 1; final color yellow = #FFFB44; final int mapEmpty = 0; final int mapGenerated = -2; //------------------------------ // C UI Generate //String name = "x11b_frame-only_sq"; //String name = "x11b_radio"; //String name = "metapixel-galaxy_corner"; //String name = "x11b_button-c"; //String name = "x11_planet|planet"; //String name = "c_twin-button"; //String name = "x11b_close"; //String name = "c_saturn"; //String name = "stars-sq3"; //String name = "b-wire_1"; //String name = "neuron-core"; //String name = "x11b_button"; //String name = "1sb_c4_wire"; final float rate = 1; final int maxLife = 5; final int maxTempLife = 1; final int iterateCount = 2; final int aliveDur = 10; final boolean useSeedImg = false; final boolean needsSeparatedSeed = true; final int maxDur = 1000; //final int ratio = 2; int[] birthCond = { 2, 3 }; int[] surviveCond = { 2, 3 }; //------------------------------ // C UI Generate Galaxy //String name = "galaxy_lg"; //final float rate = 0.5; //final int maxLife = 10; //final int maxTempLife = 4; //final int iterateCount = 1; //final int aliveDur = 8; //final boolean useSeedImg = true; //final boolean needsSeparatedSeed = false; //final int maxDur = 240; ////final int ratio = 2; //int[] birthCond = { 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // C extending line //String name = "c_extending-line_1"; //String name = "c_extending-line_2"; //String name = "c_extending-line_3"; //String name = "c_extending-line_4|a"; //String name = "c_extending-line_4|b"; //String name = "c_extending-line_5"; //String name = "c_extending-line_6|a"; //String name = "c_extending-line_6|b"; //String name = "c_extending-line_7"; //String name = "c_extending-line_8|a"; //String name = "c_extending-line_8|b"; //String name = "c_extending-line_9|a"; //String name = "c_extending-line_9|b"; //String name = "c_extending-line_10|a";; //String name = "c_extending-line_10|b"; //final float rate = 0.1; //final int maxLife = 3; //final int maxTempLife = 1; //final int iterateCount = 4; //final int aliveDur = 10; //final boolean useSeedImg = true; //final boolean needsSeparatedSeed = true; //final int maxDur = 50; ////final int ratio = 2; //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------------------------------- // main // var String[] arguments; int cx, cy; LifeLikeCA ca; int[][] map; int[][] curtDur; PImage initImg, uiImg; PImage renderImg; File[] seedFiles; PImage seedImg; boolean isFinished; int ratio; void setup() { load(); // draw frameRate( 10 ); noSmooth(); background( 0 ); } void load() { // clean dst folder File dstFolder = new File( dstDir + "/" + name ); deleteFile( dstFolder ); if ( useSeedImg ) { File seedFolder = new File( seedDir + "/" + name ); seedFiles = seedFolder.listFiles(); } if ( needsSeparatedSeed ) { String initPath = srcDir + "/" + name + "_seed.png"; String uiPath = srcDir + "/" + name + ".png"; initImg = loadImage( initPath ); uiImg = loadImage( uiPath ); } else { String initPath = srcDir + "/" + name + ".png"; initImg = loadImage( initPath ); uiImg = createImage( initImg.width, initImg.height, ARGB ); } // init ca renderImg = createImage( uiImg.width, uiImg.height, ARGB ); ca = new LifeLikeCA( initImg, birthCond, surviveCond ); ratio = renderImg.width / ca.width(); println( ratio ); if ( useSeedImg ) { ca.clear(); } // init generated map map = new int[ ca.width() ][ ca.height() ]; curtDur = new int[ ca.width() ][ ca.height() ]; for ( int y = 0; y < ca.height(); y++ ) { for ( int x = 0; x < ca.width(); x++ ) { map[ x ][ y ] = mapEmpty; } } changeWindowSize( renderImg.width * scale, renderImg.height * scale ); } void next() { if ( useSeedImg && frameCount - 1 < seedFiles.length ) { seedImg = loadImage( seedFiles[ frameCount - 1 ].getAbsolutePath() ); ca.updateSeed( seedImg ); for ( int y = 0; y < ca.height(); y++ ) { for ( int x = 0; x < ca.width(); x++ ) { if ( seedImg.get(x, y) == colorSeed && map[x][y] == mapEmpty ) { map[x][y] = 1; } } } } ca.update(); isFinished = true; for ( int y = 0; y < ca.height(); y++ ) { for ( int x = 0; x < ca.width(); x++ ) { if ( map[ x ][ y ] == mapGenerated ) { continue; } if ( xor( map[x][y] % 2 == 1, ca.field[x][y] ) ) { // if field changed map[x][y]++; curtDur[x][y] = 0; } else if ( map[x][y] != mapEmpty ) { // if not changed, increment curtDur[x][y]++; } // detect if the cell have to become "generated" if ( map[x][y] != mapEmpty ) { if ( !ca.temp[x][y] ) { if ( curtDur[x][y] == aliveDur || map[x][y] == maxLife * 2 ) { map[x][y] = mapGenerated; } } else { if ( curtDur[x][y] == aliveDur || map[x][y] == maxTempLife * 2 ) { map[x][y] = mapGenerated; } } } if ( ca.space[x][y] && (map[x][y] == mapEmpty || map[x][y] % 2 == 1) ) { isFinished = false; } } } } void draw() { println( "frame: " + (frameCount - 1) ); for ( int i = 0; i < iterateCount; i++ ) { next(); } noStroke(); background( 0 ); resetMatrix(); scale( scale ); color c; for ( int y = 0; y < ca.height(); y++ ) { for ( int x = 0; x < ca.width(); x++ ) { for ( int sy = 0; sy < ratio; sy++ ) { for ( int sx = 0; sx < ratio; sx++ ) { if ( map[x][y] == mapEmpty ) { c = 0x0; } else if ( map[x][y] % 2 == 0 ) { // dead & pseudo dead c = uiImg.get( x*ratio + sx, y*ratio + sy ); } else { c = yellow; } renderImg.set( x*ratio + sx, y*ratio + sy, c ); } } } } //tint( 0, 0, 100 ); //image( initImg, 0, 0 ); //tint( 255 ); image( renderImg, 0, 0 ); if ( isSave ) { renderImg.save( dstDir + "/" + name + "/" + name + "_" + String.format("%04d", frameCount - 1) + ".png" ); } if ( isFinished || frameCount == maxDur ) { println( "duration:" + frameCount ); exit(); } } ================================================ FILE: p5/life_like_transition/rules.pde ================================================ //// conway's game of life //int[] birthNum = { 3 }; //int[] surviveNum = { 2, 3 }; //// replicator //int[] birthNum = { 1, 3, 5, 7 }; //int[] surviveNum = { 1, 3, 5, 7 }; // small-replicator //int[] birthNum = { 2, 5 }; //int[] surviveNum = { 4 }; // 34 Life //int[] birthNum = { 3, 4 }; //int[] surviveNum = { 3, 4 }; // 2x2 //int[] birthNum = { 3, 6 }; //int[] surviveNum = { 1, 2, 5 }; // day and night //int[] birthNum = { 3, 6, 7, 8 }; //int[] surviveNum = { 3, 4, 6, 7, 8 }; // HighLife //int[] birthNum = { 3, 6 }; //int[] surviveNum = { 2, 3 }; //Morley //int[] birthNum = { 3, 6, 8 }; //int[] surviveNum = { 2, 4, 5 }; // Diamoeba //int[] birthNum = { 3, 5, 6, 7, 8 }; //int[] surviveNum = { 5, 6, 7, 8 }; // explosive one //int[] birthNum = { 1, 7 }; //int[] surviveNum = { 7, 8 }; // explosive two //int[] birthNum = { 1, 4, 5 }; //int[] surviveNum = { 3, 4 }; // gnarl //int[] birthNum = { 1, 2 }; //int[] surviveNum = { 1 }; //// coagulations //int[] birthNum = { 3, 7, 8 }; //int[] surviveNum = { 2, 3, 4, 5, 6, 7, 8 }; //// maze //int[] birthNum = { 3 }; //int[] surviveNum = { 1, 2, 3, 4, 5 }; // maze //int[] birthNum = { 1, 2, 3, 4, 5, 6 ,7, 8 }; //int[] surviveNum = { 1, 2, 3, 4, 5 }; // ameba //int[] birthNum = { 1, 3, 5, 8 }; //int[] surviveNum = { 3, 5, 7 }; // exploding chaos in seeds //int[] birthNum = { 2 }; //int[] surviveNum = { }; // coral //int[] birthNum = { 3 }; //int[] surviveNum = { 4, 5, 6, 7, 8 }; ================================================ FILE: p5/life_like_transition/settings.pde ================================================ //------------------------------ // GUI params //String name = "x11b_frame-only_sq"; //final float rate = 0.8; //final int maxLife = 2; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 40; //final boolean useSeedImg = false; //final boolean needsSeparatedSeed = true; //final int maxDur = 180; //int[] birthCond = { 1, 7 }; //int[] surviveCond = { 7, 8 }; //------------------------------ // GUI params (manual) //final float rate = 1; //final int maxLife = 2; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 10; //final boolean useSeedImg = false; //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // CUI params //final float rate = 1.0; // all //final int maxLife = 2; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 10; //final boolean useSeedImg = true; //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // Expanding ( maze, contour ) -> P //final float rate = 1; // all //final int maxLife = 2; //final int maxTempLife = 1; //final int iterateCount = 3; //final int aliveDur = 10; //final boolean useSeedImg = false; //int[] birthCond = { 3 }; //int[] surviveCond = { 1,2,3,4 }; //------------------------------ // Expanding -> B //final float rate = 1; // all //final int maxLife = 3; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 10; //final boolean useSeedImg = false; //final boolean needsSeparatedSeed = false; //int[] birthCond = { 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // Expanding -> B //String name = "city"; //final float rate = 1; // all //final int maxLife = 30000; //final int maxTempLife = 1; //final bint iterateCount = 1; //final int aliveDur = 100000; //finabl boolean useSeedImg = false; //final boolean needsSeparatedSeed = false; //int[] birthCond = { 3 }; //int[] surviveCond = { 1, 2, 3,b 4, 5 }; //------------------------------ // City Generatebbewg //String name = "city_generate"; //final float rate = 1; //final int maxLife = 3; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 10; //final boolean useSeedImg = true;bb //final boolean needsSeparatedSeed = true; //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // City Generate (fuulsize) //String name = "city_fullsize"; //final float rate = 1; //final int maxLife = 3; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 5; //final boolean useSeedImg = true; //final boolean needsSeparatedSeed = true; //final int maxDur = 180; //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // B over //String name = "b_over_2"; //String name = "b_top"; //String name = "box_gen"; //final float rate = 1; //final int maxLife = 3; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 10; //final boolean useSeedImg = false; //final boolean needsSeparatedSeed = true; //final int maxDur = 1000; //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // B side //String name = "b_side"; //final float rate = 1; //final int maxLife = 5; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 30; //final boolean useSeedImg = true; //final boolean needsSeparatedSeed = true; //final int maxDur = 275;gbg //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // Vanish //String name = "b_start_minimized"; //String name = "b_start_terminal"; //String name = "b_start_emacs"; //String name = "b_start_toolbar"; //final float rate = 1; //final int maxLife = 3; //final int maxTempLife = 1; //final int iterateCount = 1; //final int aliveDur = 30; //final boolean useSeedImg = false; //final boolean needsSeparatedSeed = true; //final int maxDur = 275; //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; //------------------------------ // B extendingv //String name = "b_start_terminal_extending"; //String name = "b_start_emacs_extending"; //String name = "b_start_toolbar_extending"; //final float rate = 1; //final int maxLife = 5; //final int maxTempLife = 1; //final int iterateCount = 3; //final int aliveDur = 20; //final boolean useSeedImg = true; //final boolean needsSeparatedSeed = false; //final int maxDur = 117; //int[] birthCond = { 2, 3 }; //int[] surviveCond = { 2, 3 }; ================================================ FILE: p5/life_like_transition/util.pde ================================================ int getStatus( PImage field, int x, int y ) { if ( x < 0 || field.width <= x || y < 0 || field.height <= y ) { return 0; } else { return field.get( x, y ) != colorDead ? 1 : 0; } } void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } String[] getArgs( String[] defaults ) { String[] arguments = new String[ defaults.length ]; try { for ( int i = 0; i < args.length; i++ ) { arguments[i] = args[i]; } } catch ( Exception e ) { } for ( int i = 0; i < defaults.length; i++ ) { if ( arguments[i] == null ) { arguments[i] = defaults[i]; } } return arguments; } void deleteFile( File f ) { if ( !f.exists() ) { return; } if ( f.isFile() ) { f.delete(); } else if ( f.isDirectory() ) { File[] files = f.listFiles(); for ( int i = 0; i < files.length; i++ ) { deleteFile( files[i] ); } f.delete(); } } boolean xor( boolean a, boolean b ) { return (a && !b) || (!a && b); } ================================================ FILE: p5/morphing/morphing.pde ================================================ //------------------------------------------------------- // cofing String srcFolder = "../_dat/lg"; int cellWidth = 4; int frameDuration = 4; float gamma = 1; boolean isSave = false; //------------------------------------------------------- // main File[] files = null; int index = 0; int counter = 0; PImage img, prevImg, changedImg; int mapWidth, mapHeight; ArrayList sides = new ArrayList(); ArrayList corners = new ArrayList(); boolean[] flgNbr = { false, false, false, false, false, false, false, false }; PVector[] neighborVec = { new PVector( 0, -1), new PVector(+1, -1), new PVector(+1, 0), new PVector(+1, +1), new PVector( 0, +1), new PVector(-1, +1), new PVector(-1, 0), new PVector(-1, -1) }; void setup() { noSmooth(); files = listImageFiles(srcFolder); println(files.length); img = loadImage(files[0].getAbsolutePath()); mapWidth = img.width; mapHeight = img.height; changedImg = createImage(mapWidth, mapHeight, ARGB); changeWindowSize(mapWidth * cellWidth, mapHeight * cellWidth); noStroke(); index++; } void draw() { background( 0 ); color c, pc; int dir; if ( counter == 0 ) { println("loading.." + index); img = loadImage(files[index].getAbsolutePath()); prevImg = loadImage(files[index-1].getAbsolutePath()); for (int y = 0; y < mapHeight; y++) { for (int x = 0; x < mapWidth; x++) { c = img.get( x, y ); pc = prevImg.get( x, y ); // detect changed pix if ( c != pc ) { dir = getDir(x, y, c); changedImg.set(x, y, color(c, dir + 1)); } else { changedImg.set(x, y, color(0)); } } } if ( ++index == files.length ) { exit(); } } // draw animation float t = float(counter) / frameDuration; t = (float) Math.pow( t, gamma ); image(prevImg, 0, 0, mapWidth * cellWidth, mapHeight * cellWidth ); for (int y = 0; y < mapHeight; y++) { for (int x = 0; x < mapWidth; x++) { c = changedImg.get(x, y); dir = int(alpha(c) - 1); if ( alpha(c) > 0 ) { resetMatrix(); scale( cellWidth ); translate( x, y ); // normal fill(color( red(c), green(c), blue(c))); if (dir == 0 ) rect(0, 0, 1, t); else if (dir == 2) rect(1-t, 0, t, 1); else if (dir == 4) rect(0, 1-t, 1, t); else if (dir == 6) rect(0, 0, t, 1); else if (dir == 1) rect(1-t, 0, t, t ); else if (dir == 3) rect(1-t, 1-t, t, t ); else if (dir == 5) rect(1-t, 0, t, t ); else if (dir == 7) rect(0, 0, t, t ); else if (dir == 9) rect((1-t)/2, (1-t)/2, t, t); } else { } } } if (isSave) { saveFrame("out/morphing_#####.png"); } // next counter = ( counter + 1 ) % frameDuration; } // radial direction //int getDir( int x, int y ) { // int dir = 9; // koritsu // // search neighbor pixels // for ( i = 0; i < neighborVec.length; i++ ) { // nx = x + int( neighborVec[i].x ); // ny = y + int( neighborVec[i].y ); // flgNbr[i] = prevImg.get( nx, ny ) == c; // } // sides.clear(); // for ( i = 0; i < flgNbr.length; i+= 2 ) { // if ( flgNbr[i] ) { // sides.add( i ); // } // } // if ( sides.size() > 0 ) { // int n = int( random( 0, sides.size() ); // dir = sides.get(n); // } else { // //dir = int( random(0, 4) * 2; // // normalized uv // float u = x / float( mapWidth ); // float v = y / float( mapHeight ); // if ( v > u ) { // if ( v > -u + 1 ) { // dir = 0; // } else { // dir = 2; // } // } else { // if ( v > -u + 1 ) { // dir = 6; // } else { // dir = 4; // } // } // } // return dir; //} // uniform direction int getDir(int x, int y, color targetColor) { int dir = 9; // alone // search neighbor pixels for (int i = 0; i < neighborVec.length; i++) { int nx = x + int(neighborVec[i].x); int ny = y + int(neighborVec[i].y); flgNbr[i] = prevImg.get(nx, ny) == targetColor; } sides.clear(); for (int i = 0; i < flgNbr.length; i+= 2) { if (flgNbr[i]) { sides.add(i); } } if (sides.size() == 3) { if (!flgNbr[0]) dir = 4; else if (!flgNbr[2]) dir = 6; else if (!flgNbr[4]) dir = 0; else if (!flgNbr[6]) dir = 2; } else if (sides.size() > 0) { int n = int(random(0, sides.size())); dir = sides.get(n); } else { corners.clear(); for (int i = 1; i < flgNbr.length; i += 2) { if (flgNbr[i]) { corners.add( i ); } } if (corners.size() > 0) { int n = int(random( 0, corners.size())); dir = corners.get(n); } } return dir; } ================================================ FILE: p5/morphing/util.pde ================================================ import java.io.FilenameFilter; void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } File[] listImageFiles(String path) { File file = new File(resolveRelativePath(path)); if (file.isDirectory()) { FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String name) { String ext = ""; int dotIndex = name.lastIndexOf('.'); if ((dotIndex > 0) && (dotIndex < name.length() - 1 )) { ext = name.substring(dotIndex + 1).toLowerCase(); } return (ext.equals("png")); } }; return file.listFiles(filter); } else { // If it's not a directory return null; } } String resolveRelativePath(String path) { File file = new File(sketchPath("") + path); try { return file.getCanonicalPath(); } catch (Exception e) { return null; } } ================================================ FILE: p5/shiki/morph.pde ================================================ int DIR_STATIC = -1; class Morph { int cellSize; int w, h; int interval = 3; float gamma = 0.7; // 1: linear PImage curtImg, prevImg; PGraphics pg; int[][] dirs; // var int counter = 0; boolean[] flgNbr = new boolean[ 8 ]; ArrayList< Integer > sides = new ArrayList< Integer >(); float t; int i, x, y, dir, nx, ny; color c, pc; // const PVector[] neighborVec = { new PVector( 0, -1 ), new PVector( +1, -1 ), new PVector( +1, 0 ), new PVector( +1, +1 ), new PVector( 0, +1 ), new PVector( -1, +1 ), new PVector( -1, 0 ), new PVector( -1, -1 ) }; Morph( int _w, int _h, int _cellSize ) { w = _w; h = _h; cellSize = _cellSize; curtImg = createImage( w, h, RGB ); prevImg = createImage( w, h, RGB ); dirs = new int[ w ][ h ]; pg = createGraphics( getWidth(), getHeight() ); } int getWidth() { return w * cellSize; } int getHeight() { return h * cellSize; } PImage getImage() { return pg.get(); } boolean availableNewFrame() { return counter == 0; } void addFrame( PImage img ) { prevImg.copy( curtImg, 0, 0, w, h, 0, 0, w, h ); curtImg.copy( img, 0, 0, w, h, 0, 0, w, h ); // diff frame for ( y = 0; y < h; y++ ) { for ( x = 0; x < w; x++ ) { c = curtImg.get( x, y ); pc = prevImg.get( x, y ); // detect changed pix if ( c != pc ) { dirs[ x ][ y ] = getDir( x, y ); } else { dirs[ x ][ y ] = DIR_STATIC; } } } } void update() { t = float( counter ) / interval; t = (float) Math.pow( t, gamma ); // animation pg.beginDraw(); pg.resetMatrix(); pg.noStroke(); pg.noSmooth(); pg.background( 0 ); pg.image( prevImg, 0, 0, getWidth(), getHeight() ); for ( y = 0; y < h; y++ ) { for ( x = 0; x < w; x++ ) { dir = dirs[ x ][ y ]; if ( dir != DIR_STATIC ) { pg.resetMatrix(); pg.scale( cellSize ); pg.translate( x, y ); // normal pg.fill( curtImg.get( x, y ) ); if ( dir == 0 ) pg.rect( 0, 0, 1, t ); else if ( dir == 2 ) pg.rect( 1-t, 0, t, 1 ); else if ( dir == 4 ) pg.rect( 0, 1-t, 1, t ); else if ( dir == 6 ) pg.rect( 0, 0, t, 1 ); else if ( dir == 1 ) pg.rect( 1-t, 0, t, t ); else if ( dir == 3 ) pg.rect( 1-t, 1-t, t, t ); else if ( dir == 5 ) pg.rect( 1-t, 0, t, t ); else if ( dir == 7 ) pg.rect( 0, 0, t, t ); else if ( dir == 9 ) pg.rect( (1-t)/2, (1-t)/2, t, t ); } } } pg.endDraw(); // increment counter counter = ( counter + 1 ) % interval; } void draw( int x, int y ) { image( pg, x, y ); } int getDir( int x, int y ) { int dir = 9; // koritsu // search neighbor pixels for ( i = 0; i < neighborVec.length; i++ ) { nx = x + int( neighborVec[i].x ); ny = y + int( neighborVec[i].y ); flgNbr[i] = prevImg.get( nx, ny ) == c; } sides.clear(); for ( i = 0; i < flgNbr.length; i+= 2 ) { if ( flgNbr[i] ) { sides.add( i ); } } if ( sides.size() > 0 ) { int n = int( random( 0, sides.size() ) ); dir = sides.get(n); } else { dir = int( random(0, 4) ) * 2; // radial uv /* float u = x / float( mapW ); float v = y / float( mapH ); if ( v > u ) { if ( v > -u + 1 ) { dir = 0; } else { dir = 2; } } else { if ( v > -u + 1 ) { dir = 6; } else { dir = 4; } }*/ } return dir; } } ================================================ FILE: p5/shiki/shiki.command ================================================ #!/bin/sh cd "/Volumes/MugiRAID1/Works/2015/13_oxff/0b" sketch="./shiki_morph" dir="../ca/shiki/01_lg/*" for d in $dir ; do if echo $d | grep 128; then p5 $sketch --args $d 8 elif echo $d | grep 256; then p5 $sketch --args $d 8 elif echo $d | grep 512; then p5 $sketch --args $d 4 elif echo $d | grep 1024; then p5 $sketch --args $d 4 fi done ================================================ FILE: p5/shiki/shiki.pde ================================================ //------------------------------------------------------- // Settings String[] defaultArgs = { "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/shiki-other/01_lg/lg_die_hard", "16" }; //------------------------------------------------------- // Processing String srcFolder; String destFolder = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/shiki/02_anim"; int cellSize; String name; File[] files = null; int index; Morph morph; UIConverter uiConverter; PImage result; void setup() { //frameRate( 60 ); frameRate( 10 ); noSmooth(); String[] arguments = getArgs( defaultArgs ); srcFolder = arguments[ 0 ]; cellSize = Integer.parseInt( arguments[ 1 ] ); files = listFiles( srcFolder ); PImage img = loadImage( files[0].getAbsolutePath() ); morph = new Morph( img.width, img.height, cellSize ); uiConverter = new UIConverter( morph.getWidth(), morph.getHeight() ); name = ( new File( srcFolder ) ).getName().replace( "_lg", "" ); changeWindowSize( morph.getWidth(), morph.getHeight() ); loadUI(); } void draw() { if ( morph.availableNewFrame() ) { PImage img = loadImage( files[ index++ ].getAbsolutePath() ); morph.addFrame( img ); } morph.update(); result = uiConverter.convert( morph.getImage() ); image( result, 0, 0 ); String frameSuffix = String.format( "%04d", (frameCount-1) ); result.save( destFolder + "/" + name + "_anim" + "/" + name + "_anim_" + frameCount + ".png" ); if ( index == files.length ) { exit(); } } ================================================ FILE: p5/shiki/ui.pde ================================================ class UI { PImage uiTopLeft, uiTopRight, uiBottomLeft, uiBottomRight, uiTop, uiRight, uiBottom, uiLeft, uiCenter; int top, right, bottom, left; String name; UI() { } UI( String path, int top, int right, int bottom, int left ) { this.top = top; this.right = right; this.bottom = bottom; this.left = left; PImage img = loadImage( path ); int w = img.width, h = img.height; uiTopLeft = decomposeToUIPart( img, 0, 0, left, top ); uiTopRight = decomposeToUIPart( img, w - right, 0, right, top ); uiBottomLeft = decomposeToUIPart( img, 0, h - bottom, left, bottom ); uiBottomRight = decomposeToUIPart( img, w - right, h - bottom, right, bottom ); uiTop = decomposeToUIPart( img, left, 0, w - left - right, top ); uiBottom = decomposeToUIPart( img, left, h - bottom, w - left - right, bottom ); uiLeft = decomposeToUIPart( img, 0, top, left, h - top - bottom ); uiRight = decomposeToUIPart( img, w - right, top, right, h - top - bottom ); uiCenter = decomposeToUIPart( img, left, top, w - left - right, h - top - bottom ); } boolean isSupport( Rect r ) { return r.w >= left + right + 1 && r.h >= top + bottom + 1; } int getMinArea() { return (left + right) * (top + bottom); } void drawToGraphics( PGraphics pg, Rect r ) { int et = r.y + top, er = r.x + r.w - right, eb = r.y + r.h - bottom, el = r.x + left, ew = r.w - left - right, eh = r.h - top - bottom; pg.image( uiTopLeft, r.x, r.y ); pg.image( uiTopRight, er, r.y ); pg.image( uiBottomLeft, r.x, eb ); pg.image( uiBottomRight, er, eb ); pg.image( uiTop, el, r.y, ew, top ); pg.image( uiBottom, el, eb, ew, bottom ); pg.image( uiLeft, r.x, et, left, eh ); pg.image( uiRight, er, et, right, eh ); pg.image( uiCenter, el, et, ew, eh ); } void draw( Rect r ) { int et = r.y + top, er = r.x + r.w - right, eb = r.y + r.h - bottom, el = r.x + left, ew = r.w - left - right, eh = r.h - top - bottom; image( uiTopLeft, r.x, r.y ); image( uiTopRight, er, r.y ); image( uiBottomLeft, r.x, eb ); image( uiBottomRight, er, eb ); image( uiTop, el, r.y, ew, top ); image( uiBottom, el, eb, ew, bottom ); image( uiLeft, r.x, et, left, eh ); image( uiRight, er, et, right, eh ); image( uiCenter, el, et, ew, eh ); } } PImage decomposeToUIPart( PImage img, int x, int y, int w, int h ) { PImage part = createImage( w, h, RGB ); part.copy( img, x, y, w, h, 0, 0, w, h ); return part; } class UIRect extends Rect { UI ui; UIRect( UI ui, Rect r ) { super( r.x, r.y, r.w, r.h ); this.ui = ui; } void draw() { ui.draw( this ); } } ================================================ FILE: p5/shiki/uiConverter.pde ================================================ import java.util.Collections; import java.util.Comparator; ArrayList< UI > uiList = new ArrayList< UI >(); String partsDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist-galaxy/_parts"; String uiPartsDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist/parts"; class UIComparator implements Comparator< UI > { public int compare(UI ui1, UI ui2) { return ui1.getMinArea() < ui2.getMinArea() ? -1 : 1; } } void loadUI() { // green //uiList.add( new UI( uiPartsDir+"/dot.png", 1, 1, 1, 1 ) ); uiList.add( new UI( uiPartsDir+"/button.png", 2, 2, 2, 2 ) ); uiList.add( new UI( uiPartsDir+"/icon.png", 6, 6, 24, 6 ) ); uiList.add( new UI( uiPartsDir+"/menu.png", 19, 2, 1, 19 ) ); uiList.add( new UI( uiPartsDir+"/button_b.png", 8, 8, 8, 8 ) ); //uiList.add( new UI( uiPartsDir+"/window_a.png", 31, 54, 31, 31 ) ); uiList.add( new UI( partsDir+"/p00.png", 3, 3, 3, 3 ) ); uiList.add( new UI( partsDir+"/p04.png", 8, 9, 8, 8 ) ); uiList.add( new UI( partsDir+"/p06.png", 8, 9, 8, 8 ) ); uiList.add( new UI( partsDir+"/p10.png", 5, 5, 13, 5 ) ); uiList.add( new UI( partsDir+"/p13.png", 6, 6, 6, 6 ) ); uiList.add( new UI( partsDir+"/p15.png", 16, 15, 14, 10 ) ); // blue //uiList.add( new UI( partsDir+"/p02.png", 1, 1, 1, 1 ) ); //uiList.add( new UI( partsDir+"/p01.png", 2, 2, 2, 2 ) ); //uiList.add( new UI( partsDir+"/p03.png", 6, 6, 6, 6 ) ); //uiList.add( new UI( partsDir+"/p07.png", 1, 1, 1, 1 ) ); //uiList.add( new UI( partsDir+"/p08.png", 8, 2, 2, 2 ) ); //uiList.add( new UI( partsDir+"/p09.png", 8, 2, 2, 6 ) ); //uiList.add( new UI( partsDir+"/p11.png", 5, 5, 13, 5 ) ); //uiList.add( new UI( partsDir+"/p12.png", 6, 6, 6, 6 ) ); //uiList.add( new UI( partsDir+"/p14.png", 16, 15, 14, 10 ) ); } class UIConverter { ArrayList< UIRect > uiRects; int w, h; PGraphics pg; // var boolean[][] done; int[][] maxArea, maxIndex; ArrayList< Rect > rects, tempRects; ArrayList isEnough; UIConverter( int _w, int _h ) { w = _w; h = _h; pg = createGraphics( w, h ); done = new boolean[w][h]; maxArea = new int[w][h]; maxIndex = new int[w][h]; rects = new ArrayList< Rect >(); tempRects = new ArrayList< Rect >(); isEnough = new ArrayList< Boolean >(); } PImage convert( PImage img ) { ArrayList< Rect > rects = searchRect( img ); //ArrayList< UI > supported = new ArrayList< UI >(); pg.beginDraw(); pg.background( 0 ); pg.noStroke(); int i, j; Rect r; UI ui = uiList.get( 0 ); int minArea = 0; for ( i = 0; i < rects.size(); i++ ) { r = rects.get( i ); ui = null; for ( j = 0; j < uiList.size(); j++ ) { if ( uiList.get(j).isSupport(r) && minArea < uiList.get(j).getMinArea() ) { ui = uiList.get(j); minArea = uiList.get(j).getMinArea(); } } if ( ui == null ) { ui = uiList.get(0); } ui.drawToGraphics( pg, r ); } pg.endDraw(); return pg.get(); } ArrayList< Rect > searchRect( PImage img ) { //rects.clear(); //isEnough.clear(); //tempRects.clear(); //int iterateNum = 1; //int x, y, x1, y1; //int curtArea; //int curtIndex; //int smallerIndex; //boolean isMax = true; //Rect r; //for ( y = 0; y < h; y++ ) { // for ( x = 0; x < w; x++ ) { // done[ x ][ y ] = img.get( x, y ) == color( 0 ); // } //} //for ( int i = 0; i < iterateNum; i++ ) { // tempRects.clear(); // isEnough.clear(); // // clear // for ( y = 0; y < h; y++ ) { // for ( x = 0; x < w; x++ ) { // maxArea[x][y] = 0; // maxIndex[x][y] = -1; // } // } // // search // for ( y = 0; y < h; y++ ) { // for ( x = 0; x < w; x++ ) { // if ( !done[x][y] ) { // r = findRect(x, y); // curtArea = r.w * r.h; // curtIndex = tempRects.size(); // // search // isMax = true; // for ( y1 = r.y; y1 <= r.bottom() && isMax; y1++ ) { // for ( x1 = r.x; x1 <= r.right(); x1++ ) { // if ( maxArea[x1][y1] < curtArea ) { // smallerIndex = maxIndex[x1][y1]; // maxIndex[x1][y1] = curtIndex; // maxArea[x1][y1] = curtArea; // //println("A"); // if ( smallerIndex != -1 ) { // isEnough.set( smallerIndex, false ); // } // } else { // isMax = false; // break; // } // } // } // if ( !isMax ) { // println("not"); // } // tempRects.add( r ); // isEnough.add( isMax ); // } // } // } //// add rects //for ( int j = 0; j < tempRects.size(); j++ ) { // if ( isEnough.get(j) ) { // r = tempRects.get(j); // rects.add( r ); // for ( y1 = r.y; y1 <= r.bottom(); y1++ ) { // for ( x1 = r.x; x1 <= r.right(); x1++ ) { // done[x1][y1] = true; // } // } // } //} //} int x, y, x1, y1; rects.clear(); for ( y = 0; y < h; y++ ) { for ( x = 0; x < w; x++ ) { done[ x ][ y ] = img.get( x, y ) == color( 0 ); } } //addRect( 16 ); addRect( 8 ); addRect( 4 ); addRect( 2 ); addRect( 1 ); return rects; } void addRect( int minWidth ) { int x, y, x1, y1; for ( y = 0; y < h; y++ ) { for ( x = 0; x < w; x++ ) { if ( !done[x][y] ) { // start searching Rect r = findRect( x, y ); if ( r.w < minWidth || r.y < minWidth ) { continue; } for ( y1 = r.y; y1 <= r.bottom(); y1++ ) { for ( x1 = r.x; x1 <= r.right(); x1++ ) { done[x1][y1] = true; } } rects.add( r ); } } } } Rect findRect( int x, int y ) { Rect r = new Rect( x, y, 1, 1 ); Rect outer = new Rect(); // expand right outer.copy( r ); do { outer.w += 1; if ( isEmptyRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true ); // expand bottom outer.copy( r ); do { outer.h += 1; if ( isEmptyRectEdge( outer ) ) { r.copy( outer ); } else { break; } } while ( true ); return r; } boolean isEmptyRectEdge( Rect r ) { if ( r.x < 0 || r.y < 0 || r.right() >= w || r.bottom() >= h ) { return false; } // horizontal edge for ( int x = r.x; x <= r.right(); x++ ) { if ( done[x][r.y] || done[x][r.bottom()] ) { return false; } } // vertical edge for ( int y = r.y; y <= r.bottom(); y++ ) { if( done[r.x][y] || done[r.right()][y] ) { return false; } } return true; } } ================================================ FILE: p5/shiki/util.pde ================================================ void changeWindowSize(int w, int h) { surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + frame.getInsets().top + frame.getInsets().bottom ); size(w, h); } //taken from http://processing.org/learning/topics/directorylist.html File[] listFiles(String dir) { File file = new File(dir); if (file.isDirectory()) { File[] files = file.listFiles(); return files; } else { // If it's not a directory return null; } } String[] getArgs( String[] defaults ) { String[] arguments = new String[ defaults.length ]; try { for ( int i = 0; i < args.length; i++ ) { arguments[i] = args[i]; } } catch ( Exception e ) { } for ( int i = 0; i < defaults.length; i++ ) { if ( arguments[i] == null ) { arguments[i] = defaults[i]; } } return arguments; } class Rect { int x, y, w, h; Rect() { x = y = w = h = 0; } Rect( int _x, int _y, int _w, int _h ) { x = _x; y = _y; w = _w; h = _h; } void print() { println( x + "\t" + y + "\t" + w + "\t" + h ); } int right() { return x + w - 1; } int bottom() { return y + h - 1; } float aspect() { return float( w ) / float( h ); } void interpolate( float t, Rect a, Rect b ) { x = int( a.x + ( b.x - a.x ) * t ); y = int( a.y + ( b.y - a.y ) * t ); w = int( a.w + ( b.w - a.w ) * t ); h = int( a.h + ( b.h - a.h ) * t ); } void draw() { rect( x, y, w, h ); } void copy( Rect r ) { x = r.x; y = r.y; w = r.w; h = r.h; } } ================================================ FILE: p5/wolfram/CA.pde ================================================ class CA { int[] cells; // An array of 0s and 1s int generation; // How many generations? int scl; // How many pixels wide/high is each cell? int[] rules; // An array to store the ruleset, for example {0,1,1,0,1,1,0,1} CA(int[] r) { rules = r; scl = 1; cells = new int[width/scl]; restart(); } // Set the rules of the CA void setRules(int[] r) { rules = r; } // Make a random ruleset void randomize() { for (int i = 0; i < 8; i++) { rules[i] = int(random(2)); } } // Reset to generation 0 void restart() { for (int i = 0; i < cells.length; i++) { cells[i] = 0; } //cells[cells.length/3] = 1; // We arbitrarily start with just the middle cell having a state of "1" for ( int i = 0; i < 5; i++ ) { cells[ int( random( cells.length ) ) ] = 1; } generation = 0; } // The process of creating the new generation void generate() { int[] nextgen = new int[cells.length]; for ( int i = 1; i < cells.length-1; i++ ) { int left = cells[i-1]; int me = cells[i]; int right = cells[i+1]; nextgen[i] = executeRules( left, me, right ); } for ( int i = 1; i < cells.length-1; i++ ) { cells[i] = nextgen[i]; } generation++; } void render() { for (int i = 0; i < cells.length; i++) { if (cells[i] == 1) { fill(255); } else { fill(0); } noStroke(); rect(i*scl,generation*scl, scl,scl); } } // Implementing the Wolfram rules // Could be improved and made more concise, but here we can explicitly see what is going on for each case int executeRules ( int a, int b, int c ) { if (a == 1 && b == 1 && c == 1) { return rules[0]; } if (a == 1 && b == 1 && c == 0) { return rules[1]; } if (a == 1 && b == 0 && c == 1) { return rules[2]; } if (a == 1 && b == 0 && c == 0) { return rules[3]; } if (a == 0 && b == 1 && c == 1) { return rules[4]; } if (a == 0 && b == 1 && c == 0) { return rules[5]; } if (a == 0 && b == 0 && c == 1) { return rules[6]; } if (a == 0 && b == 0 && c == 0) { return rules[7]; } return 0; } // The CA is done if it reaches the bottom of the screen boolean finished() { if (generation > height/scl) { return true; } else { return false; } } } ================================================ FILE: p5/wolfram/wolfram.pde ================================================ // https://processing.org/examples/wolfram.html CA ca; // An instance object to describe the Wolfram basic Cellular Automata boolean isFinished = false; void setup() { size( 640, 640 ); int[] ruleset = { 1, 0, 0, 1, 1, 0, 0, 1 }; // An initial rule system ca = new CA( ruleset ); // Initialize CA background( 0 ); } void draw() { if ( !isFinished ) { ca.render(); // Draw the CA ca.generate(); // Generate the next level } isFinished = ca.finished(); } void mousePressed() { ca.restart(); } ================================================ FILE: p5js/cell-diffuse/index.html ================================================ Untitled ================================================ FILE: p5js/cell-diffuse/save-sequence.php ================================================ ================================================ FILE: p5js/cell-diffuse/sketch-draw-maze.js ================================================ var N = 1 << 0, S = 1 << 1, W = 1 << 2, E = 1 << 3; function flood() { var frontier1 = [], i0, n0 = frontier.length, i1; // color = d3.hsl((distance += .5) % 360, 1, .5).rgb(); var i; for (i = 0; i < n0; ++i) { i0 = frontier[i] << 2; img.data[i0 + 0] = 255;//color.r; img.data[i0 + 1] = 255;//color.g; img.data[i0 + 2] = 255;//color.b; img.data[i0 + 3] = 255; } for (i = 0; i < n0; ++i) { i0 = frontier[i]; if (cells[i0] & E && !visited[i1 = i0 + 1]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & W && !visited[i1 = i0 - 1]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & S && !visited[i1 = i0 + width]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & N && !visited[i1 = i0 - width]) visited[i1] = true, frontier1.push(i1); } frontier = frontier1; return !frontier1.length; } ///////////////////////////////////////////////////////////////// function generateMaze( cellWidth, cellHeight ) { var cells = new Array(cellWidth * cellHeight), frontier = minHeap( function(a, b) { return a.weight - b.weight; } ), startIndex = (cellHeight - 1) * cellWidth; // left bottom cells[startIndex] = 0; // empty? frontier.push( {index: startIndex, direction: N, weight: Math.random()} ); frontier.push( {index: startIndex, direction: E, weight: Math.random()} ); while ( (edge = frontier.pop()) != null ) { var edge, i0 = edge.index, // i0 d0 = edge.direction, // d0 i1 = i0 + (d0 === N ? -cellWidth : d0 === S ? cellWidth : d0 === W ? -1 : +1), // neighbor cell position x0 = i0 % cellWidth, // x0 y0 = i0 / cellWidth | 0, // y0 x1, y1, d1, open = cells[i1] === undefined; // opposite not yet part of the maze if (d0 === N) { x1 = x0; y1 = y0 - 1; d1 = S; } else if (d0 === S) { x1 = x0; y1 = y0 + 1; d1 = N; } else if (d0 === W) { x1 = x0 - 1; y1 = y0; d1 = E; } else { x1 = x0 + 1; y1 = y0; d1 = W; } if (open) { cells[i0] |= d0; cells[i1] |= d1; if (y1 > 0 && cells[i1 - cellWidth] === undefined) { frontier.push({index: i1, direction: N, weight: Math.random()}); } if (y1 < cellHeight - 1 && cells[i1 + cellWidth] === undefined) { frontier.push({index: i1, direction: S, weight: Math.random()}); } if (x1 > 0 && cells[i1 - 1] === undefined) { frontier.push({index: i1, direction: W, weight: Math.random()}); } if (x1 < cellWidth - 1 && cells[i1 + 1] === undefined) { frontier.push({index: i1, direction: E, weight: Math.random()}); } } } console.log( cells ); return cells; } function minHeap(compare) { var heap = {}, array = [], size = 0; heap.array = array; heap.empty = function() { return !size; }; heap.push = function(value) { up(array[size] = value, size++); return size; }; heap.pop = function() { if (size <= 0) return; var removed = array[0], value; if (--size > 0) value = array[size], down(array[0] = value, 0); return removed; }; function up(value, i) { while ( i > 0 ) { var j = ((i + 1) >> 1) - 1, parent = array[j]; if (compare(value, parent) >= 0) break; array[i] = parent; array[i = j] = value; } } function down(value, i) { while (true) { var r = (i + 1) << 1, l = r - 1, j = i, child = array[j]; if (l < size && compare(array[l], child) < 0) child = array[j = l]; if (r < size && compare(array[r], child) < 0) child = array[j = r]; if (j === i) break; array[i] = child; array[i = j] = value; } } return heap; } ///////////////////////////////////////////////////////////////// var cells; ///////////////////////////////////////////////////////////////// // create Maze function setup() { var width = 100, height = 100; createCanvas( width * 2 + 1, height * 2 + 1 ); background( 0 ); var cells = null, distance = 0, visited = new Array(width * height), frontier = [(height - 1) * width], img = createImage( width, height ); cells = generateMaze( width, height ); stroke( 255 ); var cell, px, py; for ( var y = 0; y < height; y++ ) { for ( var x = 0; x < width; x++ ) { cell = cells[ y * width + x ]; px = 1 + x*2; py = 1 + y*2; // cell point( px, py ); // N if ( cell & N ) point( px, py-1 ); if ( cell & E ) point( px+1, py ); if ( cell & S ) point( px, py+1 ); if ( cell & W ) point( px-1, py ); } } } ================================================ FILE: p5js/cell-diffuse/sketch.js ================================================ var N = 1 << 0, S = 1 << 1, W = 1 << 2, E = 1 << 3; var MAP_W = 101; var filename = "cell-diffuse"; var exportDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/prizm"; var isSave = false; var d = new Date(); var ox = Math.floor( MAP_W / 2 ), oy = Math.floor( MAP_W / 2 ); // var ox = 0, // oy = 1; filename += "_" + ("00"+d.getDate()).substr(-2) + "-" + ("00"+d.getHours()).substr(-2) + "-" + ("00"+d.getMinutes()).substr(-2) + "-" + ("00"+d.getSeconds()).substr(-2); ///////////////////////////////////////////////////////////////// function generateMaze( cellWidth, cellHeight ) { var cells = new Array(cellWidth * cellHeight), frontier = minHeap( function(a, b) { return a.weight - b.weight; } ), startIndex = getIndex( width/2, height/2 ); // left bottom cells[startIndex] = 0; // empty? frontier.push( {index: startIndex, direction: N, weight: Math.random()} ); frontier.push( {index: startIndex, direction: E, weight: Math.random()} ); frontier.push( {index: startIndex, direction: S, weight: Math.random()} ); frontier.push( {index: startIndex, direction: W, weight: Math.random()} ); while ( (edge = frontier.pop()) != null ) { var edge, i0 = edge.index, // i0 d0 = edge.direction, // d0 i1 = i0 + (d0 === N ? -cellWidth : d0 === S ? cellWidth : d0 === W ? -1 : +1), // neighbor cell position x0 = i0 % cellWidth, // x0 y0 = i0 / cellWidth | 0, // y0 x1, y1, d1, open = cells[i1] === undefined; // opposite not yet part of the maze if (d0 === N) { x1 = x0; y1 = y0 - 1; d1 = S; } else if (d0 === S) { x1 = x0; y1 = y0 + 1; d1 = N; } else if (d0 === W) { x1 = x0 - 1; y1 = y0; d1 = E; } else { x1 = x0 + 1; y1 = y0; d1 = W; } if (open) { cells[i0] |= d0; cells[i1] |= d1; if (y1 > 0 && cells[i1 - cellWidth] === undefined) { frontier.push({index: i1, direction: N, weight: Math.random()}); } if (y1 < cellHeight - 1 && cells[i1 + cellWidth] === undefined) { frontier.push({index: i1, direction: S, weight: Math.random()}); } if (x1 > 0 && cells[i1 - 1] === undefined) { frontier.push({index: i1, direction: W, weight: Math.random()}); } if (x1 < cellWidth - 1 && cells[i1 + 1] === undefined) { frontier.push({index: i1, direction: E, weight: Math.random()}); } } } return cells; } function minHeap(compare) { var heap = {}, array = [], size = 0; heap.array = array; heap.empty = function() { return !size; }; heap.push = function(value) { up(array[size] = value, size++); return size; }; heap.pop = function() { if (size <= 0) return; var removed = array[0], value; if (--size > 0) value = array[size], down(array[0] = value, 0); return removed; }; function up(value, i) { while ( i > 0 ) { var j = ((i + 1) >> 1) - 1, parent = array[j]; if (compare(value, parent) >= 0) break; array[i] = parent; array[i = j] = value; } } function down(value, i) { while (true) { var r = (i + 1) << 1, l = r - 1, j = i, child = array[j]; if (l < size && compare(array[l], child) < 0) child = array[j = l]; if (r < size && compare(array[r], child) < 0) child = array[j = r]; if (j === i) break; array[i] = child; array[i = j] = value; } } return heap; } ///////////////////////////////////////////////////////////////// var canvas; var cells; var width = MAP_W, height = MAP_W; var distance = 0, visited = new Array( width * height ), frontier = [ getIndex( ox, oy ) ]; function getIndex( x, y ) { return Math.floor(y) * width + Math.floor(x); } function getPos( index ) { return { x: index % width, y: Math.floor( index / width ) } } function flood() { var frontier1 = [], i0, n0 = frontier.length, i1; var i; // all frontier var pos; for (i = 0; i < n0; ++i) { pos = getPos( frontier[i] ); point( pos.x, pos.y ); } for (i = 0; i < n0; ++i) { i0 = frontier[i]; if (cells[i0] & E && !visited[i1 = i0 + 1]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & W && !visited[i1 = i0 - 1]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & S && !visited[i1 = i0 + width]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & N && !visited[i1 = i0 - width]) visited[i1] = true, frontier1.push(i1); } frontier = frontier1; return !frontier1.length; } function setup() { width = MAP_W; height = MAP_W; cells = generateMaze( width, height ); var cx = Math.floor( width/2 ), cy = Math.floor( height/2 ); cells[ getIndex( cx, cy ) ] = N | E | S | W; for ( var i = 0; i < 4; i++ ) { cells[ getIndex( cx, cy-i ) ] |= N | S; cells[ getIndex( cx+i, cy ) ] |= E | W; cells[ getIndex( cx, cy+i ) ] |= N | S; cells[ getIndex( cx-i, cy ) ] |= E | W; // remove if ( i > 0 ) { removePath( cx, cy-i, E ); removePath( cx, cy-i, W ); // removePath( cx+i, cy, N ); // removePath( cx+i, cy, S ); removePath( cx, cy+i, E ); removePath( cx, cy+i, W ); // removePath( cx-i, cy, N ); // removePath( cx-i, cy, S ); } } function removePath( x, y, dir ) { var other; if ( dir == N ) other = E | S | W; else if ( dir == E ) other = N | S | W; else if ( dir == S ) otehr = N | E | W; else if ( dir == W ) other = N | E | S; cells[ getIndex( x, y ) ] &= other; } canvas = createCanvas( width, height ); background( 0 ); width = MAP_W; height = MAP_W; drawFrame(); } var frame = 0; function drawFrame() { stroke( 255, frame % 255, Math.floor( frame / 255 ) ); if ( flood() ) { return; } var frameStr = ( "000000" + frame ).substr( -6 ); var path = exportDir + "/" + filename + "/" + filename + "_" + frameStr + ".png"; data = { image: canvas.canvas.toDataURL(), path: path }; if ( isSave ) { $.post( "http://localhost:8080/save-sequence.php", data, function(data) { setTimeout( drawFrame, 5 ); } ); } else { setTimeout( drawFrame, 500 ); } frame++; } ================================================ FILE: p5js/randomized-prizm/index.html ================================================ Untitled ================================================ FILE: p5js/randomized-prizm/save-sequence.php ================================================ ================================================ FILE: p5js/randomized-prizm/sketch-draw-maze.js ================================================ var N = 1 << 0, S = 1 << 1, W = 1 << 2, E = 1 << 3; function flood() { var frontier1 = [], i0, n0 = frontier.length, i1; // color = d3.hsl((distance += .5) % 360, 1, .5).rgb(); var i; for (i = 0; i < n0; ++i) { i0 = frontier[i] << 2; img.data[i0 + 0] = 255;//color.r; img.data[i0 + 1] = 255;//color.g; img.data[i0 + 2] = 255;//color.b; img.data[i0 + 3] = 255; } for (i = 0; i < n0; ++i) { i0 = frontier[i]; if (cells[i0] & E && !visited[i1 = i0 + 1]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & W && !visited[i1 = i0 - 1]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & S && !visited[i1 = i0 + width]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & N && !visited[i1 = i0 - width]) visited[i1] = true, frontier1.push(i1); } frontier = frontier1; return !frontier1.length; } ///////////////////////////////////////////////////////////////// function generateMaze( cellWidth, cellHeight ) { var cells = new Array(cellWidth * cellHeight), frontier = minHeap( function(a, b) { return a.weight - b.weight; } ), startIndex = (cellHeight - 1) * cellWidth; // left bottom cells[startIndex] = 0; // empty? frontier.push( {index: startIndex, direction: N, weight: Math.random()} ); frontier.push( {index: startIndex, direction: E, weight: Math.random()} ); while ( (edge = frontier.pop()) != null ) { var edge, i0 = edge.index, // i0 d0 = edge.direction, // d0 i1 = i0 + (d0 === N ? -cellWidth : d0 === S ? cellWidth : d0 === W ? -1 : +1), // neighbor cell position x0 = i0 % cellWidth, // x0 y0 = i0 / cellWidth | 0, // y0 x1, y1, d1, open = cells[i1] === undefined; // opposite not yet part of the maze if (d0 === N) { x1 = x0; y1 = y0 - 1; d1 = S; } else if (d0 === S) { x1 = x0; y1 = y0 + 1; d1 = N; } else if (d0 === W) { x1 = x0 - 1; y1 = y0; d1 = E; } else { x1 = x0 + 1; y1 = y0; d1 = W; } if (open) { cells[i0] |= d0; cells[i1] |= d1; if (y1 > 0 && cells[i1 - cellWidth] === undefined) { frontier.push({index: i1, direction: N, weight: Math.random()}); } if (y1 < cellHeight - 1 && cells[i1 + cellWidth] === undefined) { frontier.push({index: i1, direction: S, weight: Math.random()}); } if (x1 > 0 && cells[i1 - 1] === undefined) { frontier.push({index: i1, direction: W, weight: Math.random()}); } if (x1 < cellWidth - 1 && cells[i1 + 1] === undefined) { frontier.push({index: i1, direction: E, weight: Math.random()}); } } } console.log( cells ); return cells; } function minHeap(compare) { var heap = {}, array = [], size = 0; heap.array = array; heap.empty = function() { return !size; }; heap.push = function(value) { up(array[size] = value, size++); return size; }; heap.pop = function() { if (size <= 0) return; var removed = array[0], value; if (--size > 0) value = array[size], down(array[0] = value, 0); return removed; }; function up(value, i) { while ( i > 0 ) { var j = ((i + 1) >> 1) - 1, parent = array[j]; if (compare(value, parent) >= 0) break; array[i] = parent; array[i = j] = value; } } function down(value, i) { while (true) { var r = (i + 1) << 1, l = r - 1, j = i, child = array[j]; if (l < size && compare(array[l], child) < 0) child = array[j = l]; if (r < size && compare(array[r], child) < 0) child = array[j = r]; if (j === i) break; array[i] = child; array[i = j] = value; } } return heap; } ///////////////////////////////////////////////////////////////// var cells; ///////////////////////////////////////////////////////////////// // create Maze function setup() { var width = 100, height = 100; createCanvas( width * 2 + 1, height * 2 + 1 ); background( 0 ); var cells = null, distance = 0, visited = new Array(width * height), frontier = [(height - 1) * width], img = createImage( width, height ); cells = generateMaze( width, height ); stroke( 255 ); var cell, px, py; for ( var y = 0; y < height; y++ ) { for ( var x = 0; x < width; x++ ) { cell = cells[ y * width + x ]; px = 1 + x*2; py = 1 + y*2; // cell point( px, py ); // N if ( cell & N ) point( px, py-1 ); if ( cell & E ) point( px+1, py ); if ( cell & S ) point( px, py+1 ); if ( cell & W ) point( px-1, py ); } } } ================================================ FILE: p5js/randomized-prizm/sketch.js ================================================ var N = 1 << 0, S = 1 << 1, W = 1 << 2, E = 1 << 3; var MAP_W = 1281; var filename = "prizm-radial"; var exportDir = "/Volumes/MugiRAID1/Works/2015/13_0xff/ca/prizm"; var isSave = false; var d = new Date(); var ox = Math.floor( MAP_W / 2 ), oy = Math.floor( MAP_W / 2 ); // var ox = 0, // oy = 1; filename += "_" + ("00"+d.getDate()).substr(-2) + "-" + ("00"+d.getHours()).substr(-2) + "-" + ("00"+d.getMinutes()).substr(-2) + "-" + ("00"+d.getSeconds()).substr(-2); ///////////////////////////////////////////////////////////////// function generateMaze( cellWidth, cellHeight ) { var cells = new Array(cellWidth * cellHeight), frontier = minHeap( function(a, b) { return a.weight - b.weight; } ), startIndex = getIndex( width/2, height/2 );//(cellHeight - 1) * cellWidth; // left bottom cells[startIndex] = 0; // empty? frontier.push( {index: startIndex, direction: N, weight: Math.random()} ); frontier.push( {index: startIndex, direction: E, weight: Math.random()} ); frontier.push( {index: startIndex, direction: S, weight: Math.random()} ); frontier.push( {index: startIndex, direction: W, weight: Math.random()} ); while ( (edge = frontier.pop()) != null ) { var edge, i0 = edge.index, // i0 d0 = edge.direction, // d0 i1 = i0 + (d0 === N ? -cellWidth : d0 === S ? cellWidth : d0 === W ? -1 : +1), // neighbor cell position x0 = i0 % cellWidth, // x0 y0 = i0 / cellWidth | 0, // y0 x1, y1, d1, open = cells[i1] === undefined; // opposite not yet part of the maze if (d0 === N) { x1 = x0; y1 = y0 - 1; d1 = S; } else if (d0 === S) { x1 = x0; y1 = y0 + 1; d1 = N; } else if (d0 === W) { x1 = x0 - 1; y1 = y0; d1 = E; } else { x1 = x0 + 1; y1 = y0; d1 = W; } if (open) { cells[i0] |= d0; cells[i1] |= d1; if (y1 > 0 && cells[i1 - cellWidth] === undefined) { frontier.push({index: i1, direction: N, weight: Math.random()}); } if (y1 < cellHeight - 1 && cells[i1 + cellWidth] === undefined) { frontier.push({index: i1, direction: S, weight: Math.random()}); } if (x1 > 0 && cells[i1 - 1] === undefined) { frontier.push({index: i1, direction: W, weight: Math.random()}); } if (x1 < cellWidth - 1 && cells[i1 + 1] === undefined) { frontier.push({index: i1, direction: E, weight: Math.random()}); } } } return cells; } function minHeap(compare) { var heap = {}, array = [], size = 0; heap.array = array; heap.empty = function() { return !size; }; heap.push = function(value) { up(array[size] = value, size++); return size; }; heap.pop = function() { if (size <= 0) return; var removed = array[0], value; if (--size > 0) value = array[size], down(array[0] = value, 0); return removed; }; function up(value, i) { while ( i > 0 ) { var j = ((i + 1) >> 1) - 1, parent = array[j]; if (compare(value, parent) >= 0) break; array[i] = parent; array[i = j] = value; } } function down(value, i) { while (true) { var r = (i + 1) << 1, l = r - 1, j = i, child = array[j]; if (l < size && compare(array[l], child) < 0) child = array[j = l]; if (r < size && compare(array[r], child) < 0) child = array[j = r]; if (j === i) break; array[i] = child; array[i = j] = value; } } return heap; } ///////////////////////////////////////////////////////////////// var canvas; var cells; var width = MAP_W, height = MAP_W; var distance = 0, visited = new Array( width * height ), frontier = [ getIndex( ox, oy ) ]; function getIndex( x, y ) { return Math.floor(y) * width + Math.floor(x); } function getPos( index ) { return { x: index % width, y: Math.floor( index / width ) } } function flood() { var frontier1 = [], i0, n0 = frontier.length, i1; // color = d3.hsl((distance += .5) % 360, 1, .5).rgb(); var i; // all frontier var pos; for (i = 0; i < n0; ++i) { pos = getPos( frontier[i] ); point( pos.x, pos.y ); //i0 = frontier[i] << 2; //img.data[i0 + 0] = 255;//color.r; //img.data[i0 + 1] = 255;//color.g; //img.data[i0 + 2] = 255;//color.b; //img.data[i0 + 3] = 255; } for (i = 0; i < n0; ++i) { i0 = frontier[i]; if (cells[i0] & E && !visited[i1 = i0 + 1]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & W && !visited[i1 = i0 - 1]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & S && !visited[i1 = i0 + width]) visited[i1] = true, frontier1.push(i1); if (cells[i0] & N && !visited[i1 = i0 - width]) visited[i1] = true, frontier1.push(i1); } frontier = frontier1; return !frontier1.length; } function setup() { width = MAP_W; height = MAP_W; cells = generateMaze( width, height ); // make grid openNeumann(); openDiagonal(); // createCanvas( width * 2 + 1, height * 2 + 1 ); canvas = createCanvas( width, height ); background( 0 ); width = MAP_W; height = MAP_W; drawFrame(); /*stroke( 255 ); var cell, px, py; for ( var y = 0; y < height; y++ ) { for ( var x = 0; x < width; x++ ) { cell = cells[ getIndex(x,y) ]; px = 1 + x*2; py = 1 + y*2; // cell point( px, py ); // N if ( cell & N ) point( px, py-1 ); if ( cell & E ) point( px+1, py ); if ( cell & S ) point( px, py+1 ); if ( cell & W ) point( px-1, py ); } }*/ } function openNeumann() { // var ox = Math.floor( width / 2 ), // oy = Math.floor( height / 2 ), // center var x, y; var i; // North x = ox, y = oy; while( y >= 0 ) { i = getIndex(x, y); cells[ i ] |= N; cells[ i ] |= S; y--; } // South x = ox, y = oy; while( y < height ) { i = getIndex(x, y); cells[ i ] |= N; cells[ i ] |= S; y++; } // West x = ox, y = oy; while( x >= 0 ) { i = getIndex(x, y); cells[ i ] |= W; cells[ i ] |= E; x--; } // East x = ox, y = oy; while( x < width ) { i = getIndex(x, y); cells[ i ] |= W; cells[ i ] |= E; x++; } } function openDiagonal() { console.log("Diagonal"); // var ox = Math.floor( width / 2 ), // oy = Math.floor( height / 2 ), // center var x, y; var i; // SE x = ox, y = oy; while( x < width ) { // x or y if ( Math.random() < .5) { // go x cells[ getIndex(x,y) ] |= E; cells[ getIndex(x+1,y) ] |= S; cells[ getIndex(x+1,y) ] |= W; cells[ getIndex(x+1,y+1) ] |= N; } else { cells[ getIndex(x,y) ] |= S; cells[ getIndex(x,y+1) ] |= N; cells[ getIndex(x,y+1) ] |= E; cells[ getIndex(x+1,y+1) ] |= W; } x++, y++; } // NW x = ox, y = oy; while( x > 0 ) { // x or y if ( Math.random() < .5) { // go x cells[ getIndex(x,y) ] |= W; cells[ getIndex(x-1,y) ] |= N; cells[ getIndex(x-1,y) ] |= E; cells[ getIndex(x-1,y-1) ] |= S; } else { cells[ getIndex(x,y) ] |= N; cells[ getIndex(x,y-1) ] |= S; cells[ getIndex(x,y-1) ] |= W; cells[ getIndex(x-1,y-1) ] |= E; } x--, y--; } // NE x = ox, y = oy; while( x < width ) { // x or y if ( Math.random() < .5) { // go x cells[ getIndex(x,y) ] |= E; cells[ getIndex(x+1,y) ] |= N; cells[ getIndex(x+1,y) ] |= W; cells[ getIndex(x+1,y-1) ] |= S; } else { cells[ getIndex(x,y) ] |= N; cells[ getIndex(x,y-1) ] |= S; cells[ getIndex(x,y-1) ] |= E; cells[ getIndex(x+1,y-1) ] |= W; } x++, y--; } // SW x = ox, y = oy; while( x > 0 ) { // x or y if ( Math.random() < .5) { // go x cells[ getIndex(x,y) ] |= W; cells[ getIndex(x-1,y) ] |= S; cells[ getIndex(x-1,y) ] |= E; cells[ getIndex(x-1,y+1) ] |= N; } else { cells[ getIndex(x,y) ] |= S; cells[ getIndex(x,y+1) ] |= N; cells[ getIndex(x,y+1) ] |= W; cells[ getIndex(x-1,y+1) ] |= E; } x--, y++; } } var frame = 0; function drawFrame() { stroke( 255, frame % 255, Math.floor( frame / 255 ) ); if ( flood() ) { return; } var frameStr = ( "000000" + frame ).substr( -6 ); var path = exportDir + "/" + filename + "/" + filename + "_" + frameStr + ".png"; data = { image: canvas.canvas.toDataURL(), path: path }; if ( isSave ) { $.post( "http://localhost:8080/save-sequence.php", data, function(data) { setTimeout( drawFrame, 5 ); } ); } else { setTimeout( drawFrame, 5 ); } frame++; } /* var r = 0; function draw() { r = (r+1) % 255; stroke( r, 255, 0 ); flood(); }*/ ================================================ FILE: readme.md ================================================ # "Subete ga F ni naru : The Perfect Insider" Ending ![](http://baku89.com/wp-content/uploads/2015/10/0xffff_ed_0013-1280x720.jpg) ## About The tools for making "[Subete ga F ni naru(すべてがFになる)](http://f-noitamina.com)", 2015 fall anime. Its story contains computer science so I adopted "generative art" approach and used p5 and Golly for simulating many kind of cellular automata. A detailed making-of articles are here: [Making of The perfect insider](https://baku89.com/making-of/ffff) NOTE: These sources are pretty tangled and it probably will not work properly on your environment. ## License This repository is published under a MIT License. See the included LICENSE file.