Categories
Generative Gestaltung

Spirographische Animation

Ein Punkt beschreibt einen Kreis und ist Ursprung eines weiteren Kreises der Ursprung eines dritten Kreises ist. Wenn man den letzten Punkt im Verlauf der Zeit studiert entstehen interessante Linien auf der Leinwand (<canvas>).

/**
 * Spirographische Animation
 * https://editor.p5js.org/matthias-jaeger-net/present/vs8G4bx6e
 * Autor: Matthias Jäger, 2020
 * Licenced MIT
 */


// CONSTANT VALUES
const CANVAS_WIDTH = 800;
const CANVAS_HEIGHT = 800;
const CENTER_X = CANVAS_WIDTH * 0.5;
const CENTER_Y = CANVAS_HEIGHT * 0.5;
const RADIUS_1 = 180;
const RADIUS_2 = RADIUS_1 * 0.5;
const RADIUS_3 = RADIUS_2 * 0.5;
const THICK = 3;

// CONSTANT TYPES
const TRACED_POINTS = [];

// NUMBER VARIABLES
let angle_1 = 0;
let angle_2 = 0;
let angle_3 = 0;
let angle_1_inc = 0;
let angle_2_inc = 0;
let angle_3_inc = 0;

// OBJECTS
let position_1;
let position_2;
let position_3;

function addPolar(v1, v2, radius, angle) {
  v1.x = v2.x + cos(radius) * angle;
  v1.y = v2.y + sin(radius) * angle;
}


// A function that is automatically called 
// a soon as the program starts

function setup() {
  createCanvas(CANVAS_WIDTH, CANVAS_HEIGHT);
  angleMode(DEGREES);
  angle_1_inc = random(-3, 3);
  angle_2_inc = random(-3, 3);
  angle_3_inc = random(-3, 3);
  position_1 = createVector();
  position_2 = createVector();
  position_3 = createVector();
}


// A function that is called 
// every frame of animation

function draw() {
  // Clear background with white
  stroke(0, 70);
  background(255);
  strokeWeight(12);

  // Translate the world coordinates to the center
  translate(CENTER_X, CENTER_Y);

  // Calculate the positions of all endpoints
  addPolar(position_1, createVector(), angle_1, RADIUS_1);
  addPolar(position_2, position_1, angle_2, RADIUS_2);
  addPolar(position_3, position_2, angle_3, RADIUS_3);

  TRACED_POINTS.push([position_3.x, position_3.y]);

  for (let v of TRACED_POINTS) {
    point(v[0], v[1]);
  }

  // radius
  strokeWeight(1);
  line(0, 0, position_1.x, position_1.y);
  line(position_1.x, position_1.y, position_2.x, position_2.y);
  line(position_2.x, position_2.y, position_3.x, position_3.y);

  // X Axis
  line(-CENTER_X, 0, CENTER_X, 0);
  line(0, -CENTER_Y, 0, CENTER_Y);

  // ellipses
  noFill();
  stroke(0, 35);
  circle(0, 0, RADIUS_1);
  circle(position_1.x, position_1.y, RADIUS_2 * 2);
  circle(position_2.x, position_2.y, RADIUS_3 * 2);

  // increment angles 
  angle_1 += angle_1_inc;
  angle_2 += angle_2_inc;
  angle_3 += angle_3_inc;
}