Skip to content

Instantly share code, notes, and snippets.

@nossidge
Last active December 14, 2015 10:19
Show Gist options
  • Save nossidge/5071479 to your computer and use it in GitHub Desktop.
Save nossidge/5071479 to your computer and use it in GitHub Desktop.
CrossOfJaggedCircles
// 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