hover = {text: "", timeout: 0},
for(let i=0; i<n_points; i++) points.push(100);
for(let i=0; i<n_fourier; i++) fourier.push(0);
200 + Math.cos(holding/n_points * TWO_PI)*30, 200 + Math.sin(holding/n_points * TWO_PI)*30,
200 + Math.cos(holding/n_points * TWO_PI)*170, 200 + Math.sin(holding/n_points * TWO_PI)*170
f = clp(f*140 + 30, 30, 170);
if(sym && holding%(n_points/2) != n_points/4) points[(n_points - holding + n_points/2)%n_points] = f;
for(let point of points) {
fill(255); stroke(0, 50);
for(let i=0; i<n_fourier*f_subdivide; i++) {
line(200 + Math.cos(i/n_fourier/f_subdivide * TWO_PI)*fo(i/n_fourier/f_subdivide), 200 + Math.sin(i/n_fourier/f_subdivide * TWO_PI)*fo(i/n_fourier/f_subdivide),
200 + Math.cos((i+1)/n_fourier/f_subdivide * TWO_PI)*fo((i+1)/n_fourier/f_subdivide), 200 + Math.sin((i+1)/n_fourier/f_subdivide * TWO_PI)*fo((i+1)/n_fourier/f_subdivide));
for(let i=0; i<n_points; i++) {
line(200 + Math.cos(i/n_points * TWO_PI)*30, 200 + Math.sin(i/n_points * TWO_PI)*30,
200 + Math.cos(i/n_points * TWO_PI)*170, 200 + Math.sin(i/n_points * TWO_PI)*170);
ellipse(200 + Math.cos(i/n_points * TWO_PI)*points[i], 200 + Math.sin(i/n_points * TWO_PI)*points[i], 10, 10);
fill(0, hover.timeout*10); noStroke();
text(hover.text, 200, 20);
hover.timeout = Math.max(0, hover.timeout - 1);
function mousePressed() {
for(let i=0; i<n_points; i++) {
let distance = dst(mouseX, mouseY, 200 + Math.cos(i/n_points * TWO_PI)*points[i], 200 + Math.sin(i/n_points * TWO_PI)*points[i]);
if(distance < min_dist || min_dist < 0) {
if(min_dist < 20) holding = choice;
function mouseReleased() {
if(key == 'e') export_data();
else if(key == 'i') import_data();
hover.text = "symmetry " + (sym ? "on" : "off");
for(let i=0; i<n_fourier; i++) fourier[i] = 0;
data = JSON.stringify({points: points, fourier: fourier});
prompt("exported data", data);
data = prompt("import data");
n_points = data.points.length;
alert("Data incorrectly formatted");