In the differential geometry of curves, a roulette is a kind of curve, generalizing cycloids, epicycloids, hypocycloids, trochoids, and involutes.
This p5.js sketch implements hypotrochoid and epicycloid roulettes.
In the differential geometry of curves, a roulette is a kind of curve, generalizing cycloids, epicycloids, hypocycloids, trochoids, and involutes.
This p5.js sketch implements hypotrochoid and epicycloid roulettes.
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<style>body {padding: 0; margin: 0; overflow: hidden;}</style> | |
</head> | |
<body> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.5/p5.min.js"></script> | |
<script src="sketch.js"></script> | |
</body> | |
</html> |
function hypotrochoid(R, r, d, theta) { | |
var x = (R - r) * cos(theta) + d * cos((R - r) / r * theta); | |
var y = (R - r) * sin(theta) - d * sin((R - r) / r * theta); | |
return createVector(x, y); | |
} | |
function epitrochoid(R, r, d, theta) { | |
var x = (R + r) * cos(theta) - d * cos((R + r) / r * theta); | |
var y = (R + r) * sin(theta) - d * sin((R + r) / r * theta); | |
return createVector(x, y); | |
} | |
function reduceFraction(n, d) { | |
var gcd = function gcd(a, b) { | |
return b ? gcd(b, a % b) : a; | |
}; | |
gcd = gcd(n, d); | |
return [n / gcd, d / gcd]; | |
} | |
var Controls = function() { | |
this.type = 0; | |
this.R = 10; | |
this.r = 6; | |
this.d = 4; | |
this.rotation = 0; | |
}; | |
var controls = new Controls(); | |
function setup() { | |
var gui = new dat.GUI({width: 400}); | |
gui.add(controls, 'type', {hypotrochoid: 0, epitrochoid: 1}); | |
gui.add(controls, 'R', 1, 32).step(1); | |
gui.add(controls, 'r', 1, 32).step(1); | |
gui.add(controls, 'd', 1, 32); | |
gui.add(controls, 'rotation', 0, 360); | |
createCanvas(windowWidth, windowHeight); | |
} | |
function windowResized() { | |
resizeCanvas(windowWidth, windowHeight); | |
} | |
function draw() { | |
var R = controls.R; | |
var r = controls.r; | |
var d = controls.d; | |
var N = reduceFraction(R, r)[1]; | |
translate(width / 2, height / 2); | |
rotate(radians(270 + controls.rotation)); | |
background(0); | |
noFill(); | |
var func = hypotrochoid; | |
if (controls.type != 0) { | |
func = epitrochoid; | |
} | |
var lo = createVector(0, 0); | |
var hi = createVector(0, 0); | |
for (var i = 0; i < 360 * N; i++) { | |
var v = func(R, r, d, radians(i)); | |
lo.x = min(lo.x, v.x); | |
lo.y = min(lo.y, v.y); | |
hi.x = max(hi.x, v.x); | |
hi.y = max(hi.y, v.y); | |
} | |
var w = hi.x - lo.x; | |
var h = hi.y - lo.y; | |
var sx = (width * 0.8) / w; | |
var sy = (height * 0.8) / h; | |
var s = min(sx, sy); | |
stroke(0, 255, 0); | |
strokeWeight(4); | |
strokeJoin(ROUND); | |
beginShape(); | |
for (var i = 0; i < 360 * N; i++) { | |
var v = func(R, r, d, radians(i)); | |
vertex(v.x * s, v.y * s); | |
} | |
endShape(CLOSE); | |
} |