Last active
December 14, 2015 10:19
-
-
Save nossidge/5071479 to your computer and use it in GitHub Desktop.
CrossOfJaggedCircles
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 = false; | |
// 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, if [starness] is 2 | |
int triangleRadius = 8; | |
// This specifies how much the shape should resemble a "star" | |
// == 1 makes a cross | |
// == 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.9; | |
// The dimensions of each cell | |
int cellW = 16; | |
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; | |
// 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 = cellW*10; | |
// Declare the Shape array | |
Shape[] shapeArray; | |
////////////////////////////////////////////////////////////////////// | |
void setup(){ | |
frameRate(20); | |
size(xCells*cellW,yCells*cellH); | |
gifCreateNew(); | |
shapeArray = new Shape[0]; | |
newPattern(centreCellX , centreCellY); | |
} | |
////////////////////////////////////////////////////////////////////// | |
void draw() { | |
background(0); | |
//////// MOUSE MOVEMENT (ToDo: Move this code to the class itself) | |
for(Shape iShape:shapeArray) { | |
iShape.inOriginalPos = false; //DEBUG | |
float distance = dist(iShape.originalPos.x,iShape.originalPos.y,mouseX,mouseY); | |
if (distance < displacement) { | |
float newDimension = max(iShape.originalDim.x, abs(distance-displacement) ); | |
float lerpAmt = 0.11; | |
iShape.cellDim.x = lerp(iShape.cellDim.x, iShape.originalDim.x + abs(distance-displacement), lerpAmt); | |
iShape.cellDim.y = lerp(iShape.cellDim.y, iShape.originalDim.y + abs(distance-displacement), lerpAmt); | |
iShape.inOriginalPos = false; | |
} else { | |
float lerpAmt = 0.11; | |
iShape.cellDim.x = lerp(iShape.cellDim.x, iShape.originalDim.x, lerpAmt); | |
iShape.cellDim.y = lerp(iShape.cellDim.y, iShape.originalDim.y, lerpAmt); | |
//iShape.set(iShape.cellDim.x, iShape.cellDim.y, 0); | |
if ( abs(iShape.cellDim.x - iShape.originalDim.x) <= 1.5 ) { | |
iShape.cellDim.x = iShape.originalDim.x; | |
iShape.cellDim.y = iShape.originalDim.y; | |
iShape.inOriginalPos = true; | |
} | |
iShape.set(iShape.originalPos.x, iShape.originalPos.y, 0); | |
} | |
} | |
//////////////////////////////////////////////////////////////////// | |
// 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.inOriginalPos==false) { | |
// Don't draw the central shape (it can overwhelm the sketch) | |
//if (centrePixX-(cellW/2)!=iShape.x && centrePixY-(cellH/2)!=iShape.y) { | |
iShape.drawShape(); | |
//} | |
} | |
} | |
} | |
//////////////////////////////////////////////////////////////////// | |
gifAddFrame(); | |
} | |
////////////////////////////////////////////////////////////////////// | |
void keyPressed(){ | |
println("pressed " + int(key) ); | |
switch( int(key) ) { | |
case 114: saveToGif=true; gifCreateNew(); break; // _R_ecord new gif | |
case 115: gifSave(); break; // _S_ave | |
case 110: newPattern(centreCellX , centreCellY); break; // _N_ew pattern | |
} | |
} | |
void stop() { | |
gifSave(); | |
} | |
////////////////////////////////////////////////////////////////////// | |
void gifCreateNew() { | |
if (saveToGif) { | |
gifExport = new GifMaker(this, System.currentTimeMillis() + ".gif"); | |
gifExport.setRepeat(0); | |
} | |
} | |
void gifAddFrame() { | |
if (saveToGif) { | |
gifExport.setDelay(frameDelay); | |
gifExport.addFrame(); | |
} | |
} | |
void gifSave() { | |
if (saveToGif) { | |
gifExport.setDelay(frameDelay); | |
gifExport.finish(); | |
saveToGif = false; | |
} | |
} | |
////////////////////////////////////////////////////////////////////// | |
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; | |
int rNum = 255-i*60; | |
int gNum = 255-i*60; | |
int bNum = 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(rNum, gNum, bNum, 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["; | |
Boolean inOriginalPos = true; | |
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.set(xCellPos*xCellW, yCellPos*yCellH, 0.0); | |
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) { | |
// Only draw the jagged quads | |
drawRandomQuad(xWidth,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); | |
} | |
//////////////////////////////////////////// | |
void drawRandomQuad() { | |
drawRandomQuad(this.cellDim.x, this.cellDim.y); | |
} | |
void drawRandomQuad(float dimensions) { | |
drawRandomQuad(dimensions, dimensions); | |
} | |
void drawRandomQuad(float xWidth, float yHeight) { | |
PVector TopLeft = new PVector(this.x, this.y, this.z); | |
PVector TopRight = new PVector(TopLeft.x + xWidth, TopLeft.y, this.z); | |
PVector BottomLeft = new PVector(TopLeft.x, TopLeft.y + yHeight, this.z); | |
PVector BottomRight = new PVector(BottomLeft.x + xWidth, BottomLeft.y, this.z); | |
float TopPointX = random(TopLeft.x, TopRight.x); | |
float BottomPointX = random(BottomLeft.x, BottomRight.x); | |
float LeftPointY = random(TopLeft.y, BottomLeft.y); | |
float RightPointY = random(TopRight.y, BottomRight.y); | |
setColors(); | |
stroke(0); | |
ellipse(TopLeft.x, TopLeft.y, xWidth, yHeight); | |
strokeWeight( 2 ); | |
fill(110,110,110,123); | |
beginShape(); | |
vertex(TopPointX, TopLeft.y); //Top | |
vertex(TopRight.x, RightPointY); //Right | |
vertex(BottomPointX, BottomLeft.y); //Bottom | |
vertex(TopLeft.x, LeftPointY); //Left | |
endShape(); | |
} | |
//////////////////////////////////////////// | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment