xxxxxxxxxx
143
let turtle
let commands = []
let theta = 0
let points = []
let index = 0
let speed = 5
let transVec;
let scl = 2
let orderSlider, sizeInput, speedSlider, animateCheck, rainbowCheck, resetButton
const mouse = () => createVector(mouseX, mouseY)
const pmouse = () => createVector(pmouseX, pmouseY)
const createDom = () => {
animateCheck = select("#animate").changed(() => index = index % points.length);
rainbowCheck = select("#rainbow");
orderSlider = select("#order").input(() => {
order = orderSlider.value()
reset()
});
speedSlider = select("#speed").input(() => {
speed = speedSlider.value();
})
}
const vecLine = (a, b) => {
line(a.x, a.y, b.x, b.y);
}
function setup() {
createCanvas(600, 600).parent("#canvas-container");
createDom()
colorMode(HSB, 360, 100, 100);
turtle = new Turtle(0, 0, 0);
size = 2;
order = orderSlider.value();
background(0)
stroke(255);
gosper_curve(order, size)
transVec = createVector()
}
function reset() {
background(0);
index = 0;
points = []
commands = []
gosper_curve(order, size)
turtle.reset()
}
function animateCurve() {
if (rainbowCheck.checked() && index >= points.length) {
rainbowCurve();
} else {
for (let i = 1; i < index; i++) {
let a = points[i - 1]
let b = points[i]
const hu = 360 * (i / index)
stroke(hu % 360, 100, 100);
vecLine(a, b);
}
}
index += min(speed, points.length - index)
}
function staticCurve() {
for (let i = 1; i < points.length; i++) {
let a = points[i - 1]
let b = points[i]
const inc = i / points.length
const hu = (360 + ((360 * inc))) % 360
stroke(hu, 100, 100);
vecLine(a, b);
}
}
function rainbowCurve() {
for (let i = 1; i < points.length; i++) {
let a = points[i - 1]
let b = points[i]
const inc = i / points.length
const hu = (360 + ((360 * inc) - theta)) % 360
stroke(hu, 100, 100);
vecLine(a, b);
}
theta = (theta + (order * 1)) % 360
}
////////////////////////////////////////////////////////////////////////
// DRAW
////////////////////////////////////////////////////////////////////////
function draw() {
translate(width / 2, height / 2);
translate(transVec.x, transVec.y);
scale(scl);
background(0);
if (animateCheck.checked()) {
animateCurve()
} else {
if (rainbowCheck.checked()) {
rainbowCurve();
} else {
staticCurve();
}
}
}
function mouseWheel(event) {
var e = Math.sign(-event.delta);
scl += 0.1 * e
scl = max(scl, .1)
}
function mouseDragged() {
if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
const dif = p5.Vector.sub(pmouse(), mouse());
transVec.add(dif.mult(-1));
}
}
function gosper_curve(order, size, is_A = true) {
const gosper_op_map = {
"-": () => turtle.right(60),
"+": () => turtle.left(60),
}
if (order == 0) {
turtle.forward(size)
return
}
const opString = is_A ? "A-B--B+A++AA+B-" : "+A-BB--B-A++A+B"
for (const op of opString) {
if (op == "A") gosper_curve(order - 1, size, true)
else if (op == "B") gosper_curve(order - 1, size, false)
else {
gosper_op_map[op]()
}
}
}