Skip to content

Instantly share code, notes, and snippets.

@fogleman
Last active December 8, 2018 09:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fogleman/c11a5cbcd845946b851518adedbf6a32 to your computer and use it in GitHub Desktop.
Save fogleman/c11a5cbcd845946b851518adedbf6a32 to your computer and use it in GitHub Desktop.
Roulette (curve)

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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment