let p = [], v=[]; let lines = []; let theta=3/2 * Math.PI, t=0, clicks=0; function setup(){ createCanvas(1000, 800); initCubicCurve(); } function draw(){ background(63); for(let i = 0; i < p.length; i++){ p[i].drawPoint(); } if(clicks > 3){ for(let i = 0; i < lines.length; i++){ lines[i].drawLine(); } lerpCubicCurve(); drawCurve(); } } function drawCurve(){ if (v.length > 100*Math.PI){v=[];} stroke(0, 255, 0, 200); strokeWeight(5); beginShape(LINES); for (let i=0; i < v.length; i++){ vertex(v[i].x, v[i].y); } endShape(); } function mouseClicked(){ if (clicks < 5) { p[clicks].changeX = mouseX; p[clicks].changeY = mouseY; } else { let c = clicks % 4; p[c].changeX = mouseX; p[c].changeY = mouseY; } v=[]; clicks ++; t=0; theta=3/2 * Math.PI; } function mouseDragged(){ p[0].changeX = mouseX; p[0].changeY = mouseY; return false; } function initCubicCurve(){ p[0] = new cPoint(0,0); p[1] = new cPoint(0,0); p[2] = new cPoint(0,0); p[3] = new cPoint(0,0); p[4] = new cPoint(0, 0); p[5] = new cPoint(0, 0); p[6] = new cPoint(0, 0); p[7] = new cPoint(0, 0); p[8] = new cPoint(0, 0); p[9] = new cPoint(0, 0); lines[0] = new cLine(p[0], p[1]); lines[1] = new cLine(p[1], p[2]); lines[2] = new cLine(p[2], p[3]); lines[3] = new cLine(p[4], p[5]); lines[4] = new cLine(p[5], p[6]); lines[5] = new cLine(p[7], p[8]); } function lerpCubicCurve(){ p[4].changeX = (1-t)*p[0].x + t * p[1].x; p[4].changeY = (1-t)*p[0].y + t * p[1].y; p[5].changeX = (1-t)*p[1].x + t * p[2].x; p[5].changeY = (1-t)*p[1].y + t * p[2].y; p[6].changeX = (1-t)*p[2].x + t * p[3].x; p[6].changeY = (1-t)*p[2].y + t * p[3].y; p[7].changeX = (1-t)*p[4].x + t * p[5].x; p[7].changeY = (1-t)*p[4].y + t * p[5].y; p[8].changeX = (1-t)*p[5].x + t * p[6].x; p[8].changeY = (1-t)*p[5].y + t * p[6].y; p[9].changeX = (1-t)*p[7].x + t * p[8].x; p[9].changeY = (1-t)*p[7].y + t * p[8].y; v.push(new cPoint(p[9].x, p[9].y)); if (theta > 2*Math.PI){theta=0;} theta += 0.01; t = (Math.sin(theta) + 1) / 2; }