master 73c9f11895ef cached
59 files
150.4 KB
48.1k tokens
43 symbols
1 requests
Download .txt
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
================================================
<languageVersion : 1.0;>

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
================================================
<languageVersion : 1.0;>

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<Integer> sides = new ArrayList<Integer>();
ArrayList<Integer> corners = new ArrayList<Integer>();

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<Boolean> 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
================================================
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Untitled</title>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.9/p5.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" type="text/javascript"></script>

    <!--<script src="libraries/p5.dom.js" type="text/javascript"></script>
    <script src="libraries/p5.sound.js" type="text/javascript"></script>-->

    <script src="sketch.js" type="text/javascript"></script>

    <style> body {padding: 0; margin: 0; background: white;} </style>
  </head>
  <body>
  </body>
</html>


================================================
FILE: p5js/cell-diffuse/save-sequence.php
================================================
<?
 header("Access-Control-Allow-Origin: *");

//canvasデータがPOSTで送信されてきた場合
$canvas = $_POST["image"];
$path = $_POST["path"];
 
//ヘッダに「data:image/png;base64,」が付いているので、それは外す
$canvas = preg_replace("/data:[^,]+,/i","",$canvas);
 
//残りのデータはbase64エンコードされているので、デコードする
$canvas = base64_decode($canvas);
 
//まだ文字列の状態なので、画像リソース化
$image = imagecreatefromstring($canvas);

$dir = dirname( $path );

if ( !file_exists( $dir ) ) {
    mkdir( $dir, 0777, true);
}

 
//画像として保存(ディレクトリは任意)
// imagesavealpha($image, false); // 透明色の有効
imagepng($image, $path );

?>

================================================
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
================================================
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Untitled</title>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.9/p5.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js" type="text/javascript"></script>

    <!--<script src="libraries/p5.dom.js" type="text/javascript"></script>
    <script src="libraries/p5.sound.js" type="text/javascript"></script>-->

    <!--<script src="sketch-draw-maze.js" type="text/javascript"></script>-->
    <script src="sketch.js" type="text/javascript"></script>

    <style> body {padding: 0; margin: 0; background: white;} </style>
  </head>
  <body>
  </body>
</html>


================================================
FILE: p5js/randomized-prizm/save-sequence.php
================================================
<?
 header("Access-Control-Allow-Origin: *");

//canvasデータがPOSTで送信されてきた場合
$canvas = $_POST["image"];
$path = $_POST["path"];
 
//ヘッダに「data:image/png;base64,」が付いているので、それは外す
$canvas = preg_replace("/data:[^,]+,/i","",$canvas);
 
//残りのデータはbase64エンコードされているので、デコードする
$canvas = base64_decode($canvas);
 
//まだ文字列の状態なので、画像リソース化
$image = imagecreatefromstring($canvas);

$dir = dirname( $path );

if ( !file_exists( $dir ) ) {
    mkdir( $dir, 0777, true);
}

 
//画像として保存(ディレクトリは任意)
// imagesavealpha($image, false); // 透明色の有効
imagepng($image, $path );

?>

================================================
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.
Download .txt
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
Download .txt
SYMBOL INDEX (43 symbols across 11 files)

FILE: golly/export-otca-metapixels.py
  function log (line 31) | def log( data ):
  function getPalette (line 34) | def getPalette():
  function main (line 48) | def main( step = 1, start = 0 ):

FILE: golly/export_large.py
  function log (line 88) | def log( data ):
  function getPalette (line 91) | def getPalette():
  function main (line 105) | def main( step = 1, start = 0 ):

FILE: golly/golly_python_script_to_output_meta-life_animation.py
  function log (line 25) | def log( data ):
  function getPalette (line 28) | def getPalette():
  function main (line 42) | def main( step = 1, start = 0 ):

FILE: golly/last-shiki.py
  function log (line 27) | def log( data ):
  function main (line 31) | def main( step = 1, start = 0 ):
  function saveImage (line 72) | def saveImage( bound, path ):
  function getImageSize (line 98) | def getImageSize( path ):
  function loadImage (line 104) | def loadImage( path ):

FILE: golly/load-image.py
  function log (line 18) | def log( data ):
  function main (line 22) | def main( step = 1, start = 0 ):

FILE: golly/rotate.py
  function log (line 16) | def log( data ):
  function main (line 19) | def main():

FILE: golly/step_generation.py
  function main (line 6) | def main():

FILE: p5js/cell-diffuse/sketch-draw-maze.js
  function flood (line 8) | function flood() {
  function generateMaze (line 40) | function generateMaze( cellWidth, cellHeight ) {
  function minHeap (line 108) | function minHeap(compare) {
  function setup (line 169) | function setup() {

FILE: p5js/cell-diffuse/sketch.js
  function generateMaze (line 27) | function generateMaze( cellWidth, cellHeight ) {
  function minHeap (line 95) | function minHeap(compare) {
  function getIndex (line 160) | function getIndex( x, y ) {
  function getPos (line 164) | function getPos( index ) {
  function flood (line 171) | function flood() {
  function setup (line 198) | function setup() {
  function drawFrame (line 256) | function drawFrame() {

FILE: p5js/randomized-prizm/sketch-draw-maze.js
  function flood (line 8) | function flood() {
  function generateMaze (line 40) | function generateMaze( cellWidth, cellHeight ) {
  function minHeap (line 108) | function minHeap(compare) {
  function setup (line 169) | function setup() {

FILE: p5js/randomized-prizm/sketch.js
  function generateMaze (line 27) | function generateMaze( cellWidth, cellHeight ) {
  function minHeap (line 95) | function minHeap(compare) {
  function getIndex (line 160) | function getIndex( x, y ) {
  function getPos (line 164) | function getPos( index ) {
  function flood (line 171) | function flood() {
  function setup (line 205) | function setup() {
  function openNeumann (line 252) | function openNeumann() {
  function openDiagonal (line 293) | function openDiagonal() {
  function drawFrame (line 380) | function drawFrame() {
Condensed preview — 59 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (168K chars).
[
  {
    "path": ".gitignore",
    "chars": 9,
    "preview": "**/out/*\n"
  },
  {
    "path": "LICENSE",
    "chars": 1080,
    "preview": "The MIT License (MIT)\nCopyright (c) 2015 Baku Hashimoto\n\nPermission is hereby granted, free of charge, to any person obt"
  },
  {
    "path": "golly/export-otca-metapixels.py",
    "chars": 2362,
    "preview": "from __future__ import division\r\n\r\nimport golly as g\r\nfrom PIL import Image\r\nfrom math import floor, ceil, log\r\nimport o"
  },
  {
    "path": "golly/export_large.py",
    "chars": 3439,
    "preview": "from __future__ import division\r\n\r\nimport golly as g\r\nfrom PIL import Image\r\nfrom math import floor, ceil, log\r\nimport o"
  },
  {
    "path": "golly/golly_python_script_to_output_meta-life_animation.py",
    "chars": 2241,
    "preview": "from __future__ import division\r\n\r\nimport golly as g\r\nfrom PIL import Image\r\nfrom math import floor, ceil, log\r\nimport o"
  },
  {
    "path": "golly/last-shiki.py",
    "chars": 2149,
    "preview": "from __future__ import division\r\n\r\nimport golly as g\r\nfrom PIL import Image\r\nfrom math import floor, ceil, log\r\nimport o"
  },
  {
    "path": "golly/load-image.py",
    "chars": 765,
    "preview": "from __future__ import division\r\n\r\nimport golly as g\r\nfrom PIL import Image\r\nfrom math import floor, ceil, log\r\nimport o"
  },
  {
    "path": "golly/rotate.py",
    "chars": 808,
    "preview": "from __future__ import division\r\n\r\nimport golly as g\r\nfrom PIL import Image\r\nfrom math import floor, ceil, log\r\nimport o"
  },
  {
    "path": "golly/step_generation.py",
    "chars": 263,
    "preview": "from __future__ import division\r\n\r\nimport golly as g\r\n\r\n\r\ndef main():\r\n\r\n\tg.run(35328)\r\n\r\n\r\n\r\n# def main():\r\n\r\n# \tw = 20"
  },
  {
    "path": "others/ResizeBorder.pbk",
    "chars": 3252,
    "preview": "<languageVersion : 1.0;>\r\n\r\nkernel ResizeBorder\r\n<   namespace : \"bk\";\r\n    vendor : \"Baku Hashimoot\";\r\n    version : 1;"
  },
  {
    "path": "others/ResizeBorderTrim.pbk",
    "chars": 3573,
    "preview": "<languageVersion : 1.0;>\r\n\r\nkernel ResizeBorderTrim\r\n<   namespace : \"bk\";\r\n    vendor : \"Baku Hashimoto\";\r\n    version "
  },
  {
    "path": "others/p5.sh",
    "chars": 428,
    "preview": "#!/bin/sh\n\nfunction usage_exit() {\n\techo \"Usage: p5 sketch-path [--args sketch-args..]\"\n\texit 1\n}\n\n\n# get full path of s"
  },
  {
    "path": "p5/cell_division_test/CellDivision.pde",
    "chars": 2868,
    "preview": "\n\nfloat gaussianRange = 4;\nfloat detail = 0.05;\nint minGen = 3;\n\n\nPGraphics divideCell( int w, int h, int minWidth ) {\n\n"
  },
  {
    "path": "p5/cell_division_test/cell_division_test.pde",
    "chars": 138,
    "preview": "\nint w = 100 + 24;\n\nvoid setup() {\n    size( 640, 640 );\n    PGraphics cell = divideCell( width, height, 10 );\n\n    imag"
  },
  {
    "path": "p5/cell_division_test/util.pde",
    "chars": 195,
    "preview": "\n\n\nvoid changeWindowSize(int w, int h) {\n\n    surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h +"
  },
  {
    "path": "p5/cubist/cubist.pde",
    "chars": 3694,
    "preview": "import java.util.Collections;\nimport ffff.*;\n\n//---------------------------------------------\n// config\n\nString srcDir ="
  },
  {
    "path": "p5/cubist/rect.pde",
    "chars": 2455,
    "preview": "\nvoid searchRect( float maxAspect, int minWidth ) {\n    \n    for ( int y = 0; y < height; y++ ) {\n        for ( int x = "
  },
  {
    "path": "p5/cubist/ui.pde",
    "chars": 5207,
    "preview": "\nString partsDir = \"/Volumes/MugiRAID1/Works/2015/13_0xff/ca/cubist/parts\";\n\nArrayList< UI > uiList = new ArrayList< UI "
  },
  {
    "path": "p5/cubist/util.pde",
    "chars": 1098,
    "preview": "class Rect {\n\n    int x, y, w, h;\n    \n    Rect() {\n        x = y = w = h = 0;\n    }\n    \n    Rect( int _x, int _y, int "
  },
  {
    "path": "p5/cubist_galaxy/cubist_galaxy.pde",
    "chars": 2491,
    "preview": "import java.util.Collections;\n\n//---------------------------------------------\n// config\n\nString srcDir = \"/Volumes/Mugi"
  },
  {
    "path": "p5/cubist_galaxy/rect.pde",
    "chars": 3111,
    "preview": "color[] colors = {\n    color(255, 0, 0),\n    color(0, 255, 0),\n    color(0, 0, 255),\n    color(255, 255, 0)\n};\n\n\nvoid lo"
  },
  {
    "path": "p5/cubist_galaxy/ui.pde",
    "chars": 6548,
    "preview": "import java.util.Collections;\nimport java.util.Comparator;  \n\nString partsDir = \"/Volumes/MugiRAID1/Works/2015/13_0xff/c"
  },
  {
    "path": "p5/cubist_galaxy/util.pde",
    "chars": 1926,
    "preview": "void changeWindowSize(int w, int h) {\n\n    surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + fr"
  },
  {
    "path": "p5/dla/Particle.pde",
    "chars": 4925,
    "preview": "// ---------------\n// Particle.pde\n// ---------------\n\n// neighbor\nint nlen = 8;\nint[] nx = {  0, +1, +1, +1,  0, -1, -1"
  },
  {
    "path": "p5/dla/Point.pde",
    "chars": 166,
    "preview": "class Point {\n    \n    int x, y;\n    \n    Point( int _x, int _y ) {\n        x = _x;\n        y = _y;\n    }\n    \n    int i"
  },
  {
    "path": "p5/dla/dla.pde",
    "chars": 1939,
    "preview": "//---------------------------------------------\n// config\n\nString weightMapPath = \"../_dat/dla-weight-map.png\";\nString d"
  },
  {
    "path": "p5/dla/util.pde",
    "chars": 1131,
    "preview": "import java.io.FilenameFilter;\n\nvoid changeWindowSize(int w, int h) {\n\n    surface.setSize( w + frame.getInsets().left +"
  },
  {
    "path": "p5/dla_animate/dla_animate.pde",
    "chars": 3174,
    "preview": "import processing.video.*;\n\n//---------------------------------------------\n// config\n\nString mapDir = \"/Volumes/MugiRAI"
  },
  {
    "path": "p5/dla_animate/ui.pde",
    "chars": 1112,
    "preview": "color uiGray = color( 204, 206, 204 ),\n      uiWhite = color( 252, 254, 252 ),\n      uiBlack = color( 124, 126, 124 );\n\n"
  },
  {
    "path": "p5/dla_animate/util.pde",
    "chars": 4017,
    "preview": "void changeWindowSize(int w, int h) {\n\n    surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + fr"
  },
  {
    "path": "p5/filling/filling.pde",
    "chars": 4933,
    "preview": "//----------------------------------------\n// config\n\nString srcDir = \"/Volumes/MugiRAID1/Works/2015/13_0xff/ca/filling/"
  },
  {
    "path": "p5/filling/util.pde",
    "chars": 192,
    "preview": "void changeWindowSize(int w, int h) {\n\n    surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + fr"
  },
  {
    "path": "p5/life_like/ca.pde",
    "chars": 3523,
    "preview": "boolean[] survive, birth;\n\n//-------------------------------------------------------\n// rules\n\n// conway's game of life\n"
  },
  {
    "path": "p5/life_like/life_like.pde",
    "chars": 802,
    "preview": "//-------------------------------------------------------\n// config\n\nfinal color colorAlive = color( 255 );\nfinal color "
  },
  {
    "path": "p5/life_like/util.pde",
    "chars": 186,
    "preview": "void changeWindowSize(int w, int h) {\n    surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + fra"
  },
  {
    "path": "p5/life_like_transition/ca.pde",
    "chars": 5265,
    "preview": "final color colorAlive = color( 200 );\nfinal color colorDead  = color( 100 );\n\nfinal color colorSeed = color( 255, 0, 0 "
  },
  {
    "path": "p5/life_like_transition/life_like_transition.pde",
    "chars": 7402,
    "preview": "//-------------------------------------------------------\n// config\n\nfinal String srcDir = \"../../ca/life-like-generatio"
  },
  {
    "path": "p5/life_like_transition/rules.pde",
    "chars": 1492,
    "preview": "//// conway's game of life\n//int[] birthNum   = { 3 };\n//int[] surviveNum = { 2, 3 };\n\n//// replicator\n//int[] birthNum "
  },
  {
    "path": "p5/life_like_transition/settings.pde",
    "chars": 4580,
    "preview": "//------------------------------\n// GUI params\n\n//String name = \"x11b_frame-only_sq\";\n\n//final float rate = 0.8;\n//final"
  },
  {
    "path": "p5/life_like_transition/util.pde",
    "chars": 1271,
    "preview": "\n\nint getStatus( PImage field, int x, int y ) {\n\n    if ( x < 0 || field.width <= x || y < 0 || field.height <= y ) {\n  "
  },
  {
    "path": "p5/morphing/morphing.pde",
    "chars": 5865,
    "preview": "//-------------------------------------------------------\n// cofing\n\nString srcFolder = \"../_dat/lg\";\n\nint cellWidth = 4"
  },
  {
    "path": "p5/morphing/util.pde",
    "chars": 1113,
    "preview": "import java.io.FilenameFilter;\n\nvoid changeWindowSize(int w, int h) {\n    surface.setSize( w + frame.getInsets().left + "
  },
  {
    "path": "p5/shiki/morph.pde",
    "chars": 4497,
    "preview": "int DIR_STATIC = -1;\n\nclass Morph {\n\n    int cellSize;\n    int w, h;\n    int interval = 3;\n    float gamma = 0.7; // 1: "
  },
  {
    "path": "p5/shiki/shiki.command",
    "chars": 361,
    "preview": "#!/bin/sh\n\ncd \"/Volumes/MugiRAID1/Works/2015/13_oxff/0b\"\n\nsketch=\"./shiki_morph\"\ndir=\"../ca/shiki/01_lg/*\"\n\n\n\nfor d in $"
  },
  {
    "path": "p5/shiki/shiki.pde",
    "chars": 1599,
    "preview": "//-------------------------------------------------------\n// Settings\n\nString[] defaultArgs = {\n   \"/Volumes/MugiRAID1/W"
  },
  {
    "path": "p5/shiki/ui.pde",
    "chars": 3142,
    "preview": "class UI {\n    \n   PImage uiTopLeft, uiTopRight, uiBottomLeft, uiBottomRight, uiTop, uiRight, uiBottom, uiLeft, uiCenter"
  },
  {
    "path": "p5/shiki/uiConverter.pde",
    "chars": 9356,
    "preview": "import java.util.Collections;\nimport java.util.Comparator;  \n\nArrayList< UI > uiList = new ArrayList< UI >();\nString par"
  },
  {
    "path": "p5/shiki/util.pde",
    "chars": 1776,
    "preview": "void changeWindowSize(int w, int h) {\n\n    surface.setSize( w + frame.getInsets().left + frame.getInsets().right, h + fr"
  },
  {
    "path": "p5/wolfram/CA.pde",
    "chars": 2726,
    "preview": "class CA {\n\n    int[] cells;     // An array of 0s and 1s \n    int generation;  // How many generations?\n    int scl;   "
  },
  {
    "path": "p5/wolfram/wolfram.pde",
    "chars": 576,
    "preview": "// https://processing.org/examples/wolfram.html\n\n\nCA ca;   // An instance object to describe the Wolfram basic Cellular "
  },
  {
    "path": "p5js/cell-diffuse/index.html",
    "chars": 633,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"UTF-8\">\n    <title>Untitled</title>\n    <script src=\"http://cdnjs.clo"
  },
  {
    "path": "p5js/cell-diffuse/save-sequence.php",
    "chars": 547,
    "preview": "<?\n header(\"Access-Control-Allow-Origin: *\");\n\n//canvasデータがPOSTで送信されてきた場合\n$canvas = $_POST[\"image\"];\n$path = $_POST[\"pat"
  },
  {
    "path": "p5js/cell-diffuse/sketch-draw-maze.js",
    "chars": 4540,
    "preview": "var N = 1 << 0,\n\tS = 1 << 1,\n\tW = 1 << 2,\n\tE = 1 << 3;\n\n\n\nfunction flood() {\n    var frontier1 = [],\n        i0,\n       "
  },
  {
    "path": "p5js/cell-diffuse/sketch.js",
    "chars": 6120,
    "preview": "var N = 1 << 0,\n\tS = 1 << 1,\n\tW = 1 << 2,\n\tE = 1 << 3;\n\t\nvar MAP_W = 101;\n\nvar filename = \"cell-diffuse\";\n\t\nvar exportDi"
  },
  {
    "path": "p5js/randomized-prizm/index.html",
    "chars": 711,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"UTF-8\">\n    <title>Untitled</title>\n    <script src=\"http://cdnjs.clo"
  },
  {
    "path": "p5js/randomized-prizm/save-sequence.php",
    "chars": 547,
    "preview": "<?\n header(\"Access-Control-Allow-Origin: *\");\n\n//canvasデータがPOSTで送信されてきた場合\n$canvas = $_POST[\"image\"];\n$path = $_POST[\"pat"
  },
  {
    "path": "p5js/randomized-prizm/sketch-draw-maze.js",
    "chars": 4540,
    "preview": "var N = 1 << 0,\n\tS = 1 << 1,\n\tW = 1 << 2,\n\tE = 1 << 3;\n\n\n\nfunction flood() {\n    var frontier1 = [],\n        i0,\n       "
  },
  {
    "path": "p5js/randomized-prizm/sketch.js",
    "chars": 8460,
    "preview": "var N = 1 << 0,\n\tS = 1 << 1,\n\tW = 1 << 2,\n\tE = 1 << 3;\n\t\nvar MAP_W = 1281;\n\nvar filename = \"prizm-radial\";\n\t\nvar exportD"
  },
  {
    "path": "readme.md",
    "chars": 686,
    "preview": "# \"Subete ga F ni naru : The Perfect Insider\" Ending\n\n![](http://baku89.com/wp-content/uploads/2015/10/0xffff_ed_0013-12"
  }
]

About this extraction

This page contains the full source code of the baku89/Subete-ga-F-ni-naru-ED GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 59 files (150.4 KB), approximately 48.1k tokens, and a symbol index with 43 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!