ArtLittle Tails

Preview image for Little Tails

Tail.pde

class Tail {
	PVector now;
	PVector[] past;
	
	float border = 12;
	
	Tail() {
		now = PVector.random2D();
		now.mult((width - (border * 2)));
		
		past = new PVector[100];
		
		for(int i = 0; i < past.length; i++) {
			past[ i ] = new PVector();
			past[ i ] = now.copy();
		}
	}
	
	void update() {
		PVector direction = PVector.random2D();
		direction.mult( random(5, 15) );
		
		now.add(direction);
		
		if(now.x > (width - border)) {
			now.x -= (now.x - (width - border));
		} else if(now.x < border) {
			now.x = (border + (border - now.x));
		}
		
		if(now.y > (height - border)) {
			now.y -= (now.y - (height - border));
		} else if(now.y < border) {
			now.y = (border + (border - now.y));
		}
	}
	
	color colorAt(float cax, float cay) {
		return color(
			map(cax, border, (width - border), 0, 255),
			map(cay, border, (height - border), 0, 255),
			map((cax * cay), (border * border), ((width - border) * (height - border)), 0, 255)
		);
	}
	
	void draw() {
		//pushMatrix();
		pushStyle();
		
		// tail
		beginShape();
		
		stroke(colorAt(now.x, now.y));
		strokeWeight(2);
		noFill();
		curveVertex(now.x, now.y);
		
		boolean opened = true;
		
		for(int i = 0; i < past.length; i++) {
			curveVertex(past[ i ].x, past[ i ].y);
			
			if((i % 3) == 0) {
				endShape();
				
				popStyle();
				
				opened = false;
				
				
				if(i < (past.length - 1)) {
					opened = true;
					
					pushStyle();
					
					beginShape();
					stroke(colorAt(past[ i ].x, past[ i ].y));
					strokeWeight(2);
					noFill();
					
					curveVertex(past[ i ].x, past[ i ].y);
				}
			}
		}
		
		if(opened) {
			endShape();
			
			popStyle();
		}
		
		// dot
		pushStyle();
		
		ellipseMode(CENTER);
		fill(colorAt(now.x, now.y));
		noStroke();
		
		ellipse(now.x, now.y, 8, 8);
		
		popStyle();
		//popMatrix();
		
		
		// reverse set tail values so the first value is ready to be set to $now
		float min_x = float(width);
		float min_y = float(height);
		
		float max_x = 0;
		float max_y = 0;
		
		for(int i = (past.length - 2); i >= 0; i--) {
			past[ (i + 1) ] = past[ i ].copy();
			
			min_x = min(min_x, past[ (i + 1) ].x);
			min_y = min(min_y, past[ (i + 1) ].y);
			
			max_x = max(max_x, past[ (i + 1) ].x);
			max_y = max(max_y, past[ (i + 1) ].y);
		}
		
		past[0] = now.copy();
		
		min_x = min(min_x, now.x);
		min_y = min(min_y, now.y);
		
		max_x = max(max_x, now.x);
		max_y = max(max_y, now.y);
		
		// outer box
		pushStyle();
		
		stroke(color(100));
		strokeWeight(2);
		noFill();
		
		rect(
			(min_x - 3),
			(min_y - 3),
			((max_x - min_x) + 6),
			((max_y - min_y) + 6)
		);
		
		popStyle();
	}
}

little_tails.pde

Tail tails;

void setup() {
	size(640, 640);
	tails = new Tail();
}

void draw() {
	background(30);
	
	tails.update();
	tails.draw();
	
	if(frameCount == 350) { save("preview.png"); }
}
pyxol © 2023
built with React + Next.js