xxxxxxxxxx
121
// Inverse of Cantor's pairing function
function to_pair(z) {
let s = sqrt(8*z + 1);
let w = floor( (s - 1) / 2 );
let t = w * (w + 1) / 2;
let y = z - t;
let x = w - y;
return [x, y];
}
// Cantor's pairing function
function from_pair(x, y) {
return (x + y + 1) * (x + y) / 2 + y;
}
// OEIS A277577
let next_n = function() {
let a = 0, b = 0, c = 0, d = -1, n = -1;
return function() {
while(true) {
c = c > 0 ? c - 1 : a++;
if(d < b) d++;
else { d = 0; b++; }
n++;
if(0 < c && c < d && (c + d) % 2) {
return n;
}
}
}
}();
function pythag_triple(n, m) {
let m2 = m*m, n2 = n*n;
return [ m2 - n2, 2*m*n, m2 + n2];
}
function closest_triple(x, y) {
let m = (abs(x) + sqrt(x*x + y*y)) / 2;
m = round(sqrt(m));
let n = round( abs(y)/(2 * m) );
return pythag_triple(n, m);
}
function circle_div(r, n) {
let a = 2*PI/n;
let b = 0;
stroke("darkred");
strokeWeight(0.5);
circle(width/2, height/2, r*2);
strokeWeight(2);
while(b < 2*PI) {
let x = r*cos(b);
let y = r*sin(b);
b = b + a;
strokeWeight(0.5);
line(width/2 + x, height/2 - y, width/2, height/2);
}
}
let scale = 1;
let radius = 2000;
function mouseClicked() {
let x = (mouseX - width/2) / scale;
let y = (height/2 - mouseY) / scale;
let t = closest_triple(x, y);
x = x/abs(x) * t[0];
y = y/abs(y) * t[1];
print(x, y);
let ang = atan2(y,x);
x = radius * cos(ang);
y = radius * sin(ang);
stroke("green");
line(width/2,height/2, width/2+x, height/2-y);
}
function setup() {
noLoop();
createCanvas(8200, 4200);
background(0);
strokeWeight(2);
noFill();
scrollTo((width - windowWidth)/2,
(height - windowHeight)/2);
let tri = 31;
let max = tri*(tri+1)/2;
let u = 1, v = 1, w = 3;
point(width/2 + 0, height/2 - 0);
for(let i = 0; i < max; i++) {
let j = next_n();
let k = to_pair(j);
let t = pythag_triple(k);
let [a, b, c] = t;
[a, b, c] = [a*scale, b*scale, c*scale];
stroke("white");
point(width/2 + a, height/2 - b);
point(width/2 - a, height/2 - b);
point(width/2 - a, height/2 + b);
point(width/2 + a, height/2 + b);
if(v == 0) {
v = u = u + 1;
stroke("white");
point(width/2 + w*w*scale, height/2);
point(width/2 - w*w*scale, height/2);
w = w + 2;
}
v = v - 1;
}
stroke("white");
point(width/2 + w*w*scale, height/2);
point(width/2 - w*w*scale, height/2);
circle_div(radius*scale, 60);
}
function draw() {
}