rose curve + augmented hypocycloid

mouseX rotates and changes the size of the hypocycloid (thicker lines, filled shape). mouseY corresponds with n, which essentially determines the complexity of the curves. it took me a while to finish this because I was having too much fun spacing out while playing with it…

sketch
// jaden luscher
// jluscher@andrew.cmu.edu
// section a
// project 07: composition with curves
// HYPOCYCLOID PEDAL CURVE + ROSE CURVE

// INITIALIZING VARIABLES
var nPoints = 250;
var n;
var a;
var q;

function setup() {
  createCanvas(400, 400);
  background(200);

  frameRate(30);

}

function draw() {
  background("orange");
  noFill();

  q = constrain((mouseX / width), 0.1, 1.0);
  p = constrain((mouseY / height), 0.1, 1.0);
  n = int(p * 100);   // n corresponds to the curves' complexity
  a = int(width * p * 10);    // "radius" of rose curve increades with mouseY
  var c = 155 + (q * 100);  // fill color for hypocycloid

  translate (width/2, height/2);
  strokeWeight(q *20);    // stroke of hypocycloid corresponds to mouseX
  stroke("white");
  fill(c, 0, c, 5);
  for (i = 0; i < nPoints/10; i++) {
    drawHypocycloid();
    a = a *sqrt(q) - width*q;   // sqaure root causes many curve sizes to "cross"
  }
  a = int(width * p * 10);    // "radius" of rose curve increades with mouseY
  stroke("white");
  strokeWeight(0.5);
  rotate(PI * q);   // rose curve spins with mouseX
  drawRoseCurve();
}


function drawHypocycloid() {
  // hypocycloid pedal curve:
  // https://mathworld.wolfram.com/HypocycloidPedalCurve.html
  push();

  var x;
  var y;
  var r;

  beginShape();
  for (var i = 0; i < nPoints; i++) {
    var t = map(i, 0, nPoints, 0, TWO_PI);// sweep theta from 0 to two pi

    // hypocycloid:
    r = q * (n-2) * ((sin * (n / (n-2))) * (t + PI/2));

    x = a * (((n-1) * cos(t) + cos((n-1) * t)) / n);
    y = a * (((n-1) * sin(t) + sin((n-1) * t)) / n);
    vertex(x, y);
  }
  endShape(CLOSE);
  pop();
}


function drawRoseCurve() {
  // rose curve
  // https://mathworld.wolfram.com/RoseCurve.html

  push();
  var x;
  var y;
  var r;

  beginShape();
  for (var i = 0; i < nPoints; i++) {
    var t = map(i, 0, nPoints, 0, TWO_PI);// sweep theta from 0 to two pi
    r = a * p  * cos(n * t);

// pasted from hypercycloid
    x = r * cos(t);
    y = r * sin(t);
    vertex(x, y);
  }
  endShape(CLOSE);
  pop();

}

Leave a Reply