Created
February 23, 2013 17:48
-
-
Save nossidge/5020640 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Save as animated GIF | |
// Requires gifAnimation Processing Library | |
// http://www.extrapixel.ch/processing/gifAnimation/ | |
import gifAnimation.*; | |
GifMaker gifExport; | |
boolean saveToGif = true; | |
// The time between GIF frames | |
int frameDelay = 60; | |
// No of cells between the centre and edge DIAGONALLY | |
// It's kind of confusing, but it makes sense in the code | |
// Works nicely between 4 to 6 | |
int triangleRadius = 8; | |
// This specifies how much the shape should resemble a "star" | |
// == 1 makes a cros | |
// == 2 makes a square diamond | |
// >= 2 makes a star | |
float starness = 2.7; | |
// Cell will be drawn if the RNG is below 1 | |
// So a value of 3 will draw about 1/3 of the cells | |
//float randomUpperLimit = 1.5; | |
float randomUpperLimit = 1; | |
// The dimensions of each cell | |
int cellW = 8; | |
int cellH = cellW; | |
// The ideal pixel size for the canvas | |
int yPixelIdeal = cellW*34; | |
int xPixelIdeal = int(yPixelIdeal * 1); | |
// Has to be an odd number to make sure we have a central pixel | |
int xCells = (xPixelIdeal / cellW) + 1; | |
int yCells = (yPixelIdeal / cellH) + 1; | |
// Find central cell | |
int centreCellX = (xCells - 1) / 2; | |
int centreCellY = (yCells - 1) / 2; | |
int centrePixX = xCells*cellW/2; | |
int centrePixY = yCells*cellH/2; | |
// Move automatically, or mouse? | |
Boolean moversMove = true; | |
// This is the one in the center | |
PVector moverCenterLoc = new PVector(centrePixX,centrePixY); | |
PVector moverCenterVel = new PVector(1,1); | |
// Mouse/Mover distance of effect | |
int displacement = 77; | |
// Declare the Shape array | |
Shape[] shapeArray; | |
////////////////////////////////////////////////////////////////////// | |
void setup(){ | |
frameRate(20); | |
size(xCells*cellW,yCells*cellH); | |
if (saveToGif) { | |
gifExport = new GifMaker(this, System.currentTimeMillis() + ".gif"); | |
gifExport.setRepeat(0); | |
} | |
shapeArray = new Shape[0]; | |
newPattern(centreCellX , centreCellY); | |
} | |
////////////////////////////////////////////////////////////////////// | |
void draw() { | |
background(0); | |
//////////////////////////////////////////////////////////////////// | |
// http://processing.org/discourse/beta/num_1264000877.html | |
int maxFrames = 50; | |
if (moversMove) { | |
//int r = 19; | |
int r = 55; | |
// I really need to base this on frameCount... | |
float t = millis()/400.0f; | |
//float t = frameCount; | |
int x = (int)(centrePixX+r*cos(t)); | |
int y = (int)(centrePixY+r*sin(t)); | |
moverCenterLoc.set(x-2, y-2, 0); | |
for(Shape iShape:shapeArray) { | |
float distance = dist(iShape.x,iShape.y,moverCenterLoc.x,moverCenterLoc.y); | |
if (distance < displacement) { | |
float newDimension = max(iShape.originalDim.x, abs(distance-displacement) ); | |
iShape.cellDim.x = newDimension; | |
iShape.cellDim.y = newDimension; | |
} else { | |
iShape.cellDim.x = iShape.originalDim.x; | |
iShape.cellDim.y = iShape.originalDim.y; | |
} | |
} | |
} | |
//////////////////////////////////////////////////////////////////// | |
//////// MOUSE | |
if (!moversMove) { | |
for(Shape iShape:shapeArray) { | |
float distance = dist(iShape.x,iShape.y,mouseX,mouseY); | |
if (distance < displacement) { | |
float newDimension = max(iShape.originalDim.x, abs(distance-displacement) ); | |
iShape.cellDim.x = newDimension; | |
iShape.cellDim.y = newDimension; | |
} else { | |
iShape.cellDim.x = iShape.originalDim.x; | |
iShape.cellDim.y = iShape.originalDim.y; | |
} | |
} | |
} | |
///////////////////////////// | |
//////////////////////////////////////////////////////////////////// | |
// Loop through the array and draw each element | |
//for(Shape iShape:shapeArray) { iShape.drawShape(); } | |
for(int i=triangleRadius-1;i>=0;i--){ | |
for(Shape iShape:shapeArray) { | |
if (iShape.zLayer==i) { | |
iShape.drawShape(); | |
} | |
} | |
} | |
//////////////////////////////////////////////////////////////////// | |
// Show the mover | |
//rect(moverCenterLoc.x, moverCenterLoc.y, 2, 2); | |
// Only add the first few frames, to make it loop nicely. | |
// The number (declared above) is a bit guessworky, I'm afraid. | |
if (frameCount<maxFrames) { | |
addToGif(); | |
} | |
} | |
////////////////////////////////////////////////////////////////////// | |
void keyPressed(){ | |
background(0); | |
newPattern(centreCellX , centreCellY); | |
addToGif(); | |
} | |
void stop() { | |
if (saveToGif) { | |
gifExport.setDelay(frameDelay); | |
gifExport.finish(); | |
} | |
} | |
////////////////////////////////////////////////////////////////////// | |
void addToGif() { | |
if (saveToGif) { | |
gifExport.setDelay(frameDelay); | |
gifExport.addFrame(); | |
} | |
} | |
////////////////////////////////////////////////////////////////////// | |
void newPattern(int centreCellX, int centreCellY) { | |
background(0); | |
// Clear the array | |
shapeArray = new Shape[0]; | |
for(int i=0;i<triangleRadius;i++){ | |
for(int j=0;j<( (triangleRadius*2) - (starness*i) );j++){ | |
// Colour grey | |
int greyNum = 255-i*60; | |
// Split the square into eighths, and have each square in each eighth behave the same | |
//if (random(randomUpperLimit)<1) { | |
if (random(randomUpperLimit)<1 && greyNum >60 ) { | |
color fillColor = color(greyNum, greyNum, greyNum, 33); | |
int sector=1; | |
Shape newShape; | |
newShape = new Shape((centreCellX+i), (centreCellY-j-i), cellW, cellH, fillColor, color(0), sector++, i); | |
shapeArray = (Shape[]) append(shapeArray, newShape); | |
newShape = new Shape((centreCellX+j+i), (centreCellY-i), cellW, cellH, fillColor, color(0), sector++, i); | |
shapeArray = (Shape[]) append(shapeArray, newShape); | |
newShape = new Shape((centreCellX+j+i), (centreCellY+i), cellW, cellH, fillColor, color(0), sector++, i); | |
shapeArray = (Shape[]) append(shapeArray, newShape); | |
newShape = new Shape((centreCellX+i), (centreCellY+j+i), cellW, cellH, fillColor, color(0), sector++, i); | |
shapeArray = (Shape[]) append(shapeArray, newShape); | |
newShape = new Shape((centreCellX-i), (centreCellY+j+i), cellW, cellH, fillColor, color(0), sector++, i); | |
shapeArray = (Shape[]) append(shapeArray, newShape); | |
newShape = new Shape((centreCellX-j-i), (centreCellY+i), cellW, cellH, fillColor, color(0), sector++, i); | |
shapeArray = (Shape[]) append(shapeArray, newShape); | |
newShape = new Shape((centreCellX-j-i), (centreCellY-i), cellW, cellH, fillColor, color(0), sector++, i); | |
shapeArray = (Shape[]) append(shapeArray, newShape); | |
newShape = new Shape((centreCellX-i), (centreCellY-j-i), cellW, cellH, fillColor, color(0), sector++, i); | |
shapeArray = (Shape[]) append(shapeArray, newShape); | |
} | |
} | |
} | |
} | |
////////////////////////////////////////////////////////////////////// | |
class Shape extends PVector { | |
String defaultShape = "rect"; | |
PVector originalPos = new PVector(); | |
PVector originalDim = new PVector(); | |
PVector cellPos = new PVector(); | |
PVector cellDim = new PVector(); | |
color fill; | |
color stroke; | |
int sector; // The number of the eighth | |
int zLayer; // White should be on top, so draw them last | |
int drawOrigin = CENTER; // Supports CORNER and CENTER only | |
//////////////////////////////////////////// | |
Shape(float xCellPos, float yCellPos, | |
float xCellW, float yCellH, | |
color inputFill, color inputStroke, | |
int inputSector, int zLayer) { | |
cellPos.set(xCellPos, yCellPos, 0.0); | |
cellDim.set(xCellW, yCellH, 0.0); | |
originalPos = cellPos.get(); | |
originalDim = cellDim.get(); | |
this.set(xCellPos*xCellW, yCellPos*yCellH, 0.0); | |
this.fill = inputFill; | |
this.stroke = inputStroke; | |
this.sector = inputSector; | |
this.zLayer = zLayer; | |
} | |
//////////////////////////////////////////// | |
// CENTER is more accurate, but CORNER is more weird | |
void setColors() { | |
fill(fill); | |
stroke(stroke); | |
ellipseMode(drawOrigin); | |
rectMode(drawOrigin); | |
} | |
void setDrawOrigin(int originType){ | |
this.drawOrigin = originType; | |
} | |
//////////////////////////////////////////// | |
void drawShape() { | |
drawShape(this.cellDim.x, this.cellDim.y); | |
} | |
void drawShape(float dimensions) { | |
drawShape(dimensions, dimensions); | |
} | |
void drawShape(float xWidth, float yHeight) { | |
if (defaultShape == "rect") { | |
drawRect(xWidth,yHeight); | |
} else { | |
drawEllipse(xWidth,yHeight); | |
} | |
} | |
//////////////////////////////////////////// | |
void drawEllipse() { | |
drawEllipse(this.cellDim.x, this.cellDim.y); | |
} | |
void drawEllipse(float dimensions) { | |
drawEllipse(dimensions, dimensions); | |
} | |
void drawEllipse(float xWidth, float yHeight) { | |
setColors(); | |
// If CORNER | |
float xPos = this.x; | |
float yPos = this.y; | |
if (drawOrigin==CENTER) { | |
xPos = this.x + (this.originalDim.x / 2); | |
yPos = this.y + (this.originalDim.y / 2); | |
} | |
ellipse(xPos, yPos, xWidth, yHeight); | |
} | |
//////////////////////////////////////////// | |
void drawRect() { | |
drawRect(this.cellDim.x, this.cellDim.y); | |
} | |
void drawRect(float dimensions) { | |
drawRect(dimensions, dimensions); | |
} | |
void drawRect(float xWidth, float yHeight) { | |
setColors(); | |
// If CORNER | |
float xPos = this.x; | |
float yPos = this.y; | |
if (drawOrigin==CENTER) { | |
xPos = this.x + (this.originalDim.x / 2); | |
yPos = this.y + (this.originalDim.y / 2); | |
} | |
rect(xPos, yPos, xWidth, yHeight); | |
} | |
//////////////////////////////////////////// | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment