xxxxxxxxxx
236
/* (WIP)
This is a visualiser for paper folds
TODO
interpolate speed between nice angles
zoom scalen met image size
*/
const foldset1 = { folds:"MVMVMVMVMVMVMVMV",
setnumber:1,
answer:16 };
const foldset2 = { folds:"VVMVVMMVVVMMVMM",
setnumber:"2 (dragon curve)",
answer:4 };
const foldset4 = { folds:"VVMMMVMVVVMVMMMVV",
setnumber:"4 (square)",
answer:4 };
.
var foldsets = [foldsetDragonCurve, order11DragonTwins, foldset1, foldset2, foldset3, foldset4, foldset34,foldset38,foldset41, foldsetCustom,foldsetImpossible,stackedDiamonds,custominput];
const DEFAULT_ANGLE = 0;
const DEFAULT_ZOOM = 4;
const ANGLE_STEP = 0.01;
const SPEED_STEP = 0.01; // TODO: make this a slider too lol
const MAX_SPEED = 5;
const START_SPEED = 0.02;
const MIN_SPEED = -5;
var foldindex = 0;
var DEMO = true;
var DRAWFOLDNAME = false;
var customInterval = 5;
forward = true;
const FPS = 60;
// create sliders
function crts(x,y, name, mini, maxi, start, step){
container = createDiv(name)
slid = createSlider(mini, maxi, start, step);
container.position(x,y);
slid.parent(container);
return slid ;
}
function setup() {
createCanvas(400, 400);
frameRate(FPS);
createButton('Next set of folds')
.mouseReleased(updateButton);
createButton('toggle demo')
.mouseReleased(toggleDemo);
createButton('draw fold names')
.mouseReleased(() => DRAWFOLDNAME = !DRAWFOLDNAME);
// slider for ZOOM
lineSlider = crts(10, 450, `<p id = "zoomText">zoom: ${DEFAULT_ZOOM}</p>`, 0, 100, DEFAULT_ZOOM, 1)
lineSlider.input(lineSliderHasBeenTouched);
// slider for the angle of the fold
angleSlider = crts(10, 550, `<p id = "angleText">angle: ${DEFAULT_ANGLE}</p>`, -360, 360, DEFAULT_ANGLE, ANGLE_STEP)
angleSlider.input(angleSliderHasBeenTouched);
// speed slider
speedSlider = crts(10, 650, `<p id = "speedText">speed: ${START_SPEED}</p>`, MIN_SPEED, MAX_SPEED, START_SPEED, SPEED_STEP)
speedSlider.input(speedSliderHasBeenTouched);
createButton('reset angle')
.mouseReleased(()=> {angleSlider.value(0); angleSliderHasBeenTouched();
angleInput.value(0)} );
// number input with /\ \/ to select, typing also works
// this sets the angle to a precise number. its restricted for whole ints
angleInput = createInput('0', 'number').input(() => {
angleSlider.value(angleInput.value());
angleSliderHasBeenTouched();
})
addBtn = createButton('add 5°')
.mouseReleased(()=> {
angleSlider.value(angleSlider.value()+5); angleSliderHasBeenTouched();
angleInput.value(angleSlider.value()+5)
} );
subBtn = createButton('sub 5°')
.mouseReleased(()=> {
angleSlider.value(angleSlider.value()-5);
angleInput.value(angleSlider.value()-5)
angleSliderHasBeenTouched();
} );
customFold = createInput('')
customFold.input(visCustomFold);
}
var stripIllegal = new RegExp('[^VM]', 'g');
function visCustomFold(){
f = customFold.value().toUpperCase().replace(stripIllegal,'');
if (f == '') { return }
custominput.folds = f;
custominput.setnumber = `custom`,
custominput.answer = "";
foldindex = (foldsets.length-1)
visfolds(foldsets[foldindex]);
}
function mapSpeed(s){ //TODO
// make slider more comfortable around 0
// return map(s**2, 0, 10**2, MIN_SPEED, MAX_SPEED)
// return unimplemented.
}
function toggleDemo () {
DEMO = !DEMO;
visfolds(foldsets[foldindex]);
text('demo is off', 0, 390);
loop();
}
function speedSliderHasBeenTouched(){
if (angleSlider.value() >= 360) { forward = false;}
if (angleSlider.value() <= -360) { forward = true; }
document.getElementById("speedText").innerHTML = `speed: ${speedSlider.value()}`;
visfolds(foldsets[foldindex]);
}
function lineSliderHasBeenTouched(){
document.getElementById("zoomText").innerHTML = `zoom: ${lineSlider.value()}`;
visfolds(foldsets[foldindex]);
}
function angleSliderHasBeenTouched(){
DEMO=false;
document.getElementById("angleText").innerHTML = `angle: ${angleSlider.value().toFixed(2)} (${radians(angleSlider.value()).toFixed(1)})`;
angleInput.value(angleSlider.value());
visfolds(foldsets[foldindex]);
}
function updateButton(){
foldindex = (foldindex+1)%foldsets.length;
visfolds(foldsets[foldindex]);
}
function visfolds(foldset) {
background('white');
ans = foldset.answer
folds = foldset.folds
var x = 200;
var y = 200;
var currentAngle = DEFAULT_ANGLE;
var angleSize = angleSlider.value();
var lineSize = lineSlider.value();
col = 0;
colorMode(HSB);
for (var i = 0; i < folds.length+1 ; i++){
stroke(map(i,0,folds.length,0,255),100,100, 100);
actualAngle = radians(currentAngle);
var xx = x + (lineSize * cos(actualAngle))
var yy = y + (lineSize * sin(actualAngle))
line(x,y,xx,yy);
if (DRAWFOLDNAME ) {
text(folds[i], xx,yy)
}
x=xx;
y=yy;
if (folds[i] == "M") { currentAngle -= (angleSize+90);}
else if (folds[i] == "V") { currentAngle += (angleSize+90);}
}
colorMode(RGB);
fill('red');
textSize(12);
text(`problem ${foldsets[foldindex].setnumber}`, 25, 25);
text(`this takes at least ${foldsets[foldindex].answer} folds`, 25, 38);
text(folds, 25, 50);
}
function draw() {
if (DEMO) {
var d = speedSlider.value();
if (angleSlider.value() >= 360) { forward = false;}
if (angleSlider.value() <= -360) { forward = true; }
if (forward){
angleSlider.value(angleSlider.value()+d);
} else {
angleSlider.value(angleSlider.value()-d);
}
document.getElementById("angleText").innerHTML = `angle: ${angleSlider.value().toFixed(2)} (${radians(angleSlider.value()).toFixed(1)})`;
visfolds(foldsets[foldindex]);
angleInput.value(angleSlider.value().toFixed(0));
text('demo is on', 0, 390);
} else {
noLoop();
}
}