Hidden circle removal

Super slow for extra enjoyment.

Log in to post a comment.

```Canvas.setpenopacity(1);

const precision = 300; /// min=3 max=1000 step=1
const concentric = 50; // min=1 max=100 step=1
const density = 0.25; // min=0.0.1 max=3 step=0.01
const radius = 90; // min=0 max=300 step=1
const epicenters = 25; // min=1 max=1000 step=1
const variation = 0.0; // min=0 max=0.5 step=0.01
const frequency = 4; // min=1 max=10 step=0.1

const turtle = new Turtle();

let circle_list;
let radius_t = radius;

let epicenter_list;

function walk(i, t) {
if (i == 0) {
circle_list = [];

epicenter_list = [];
while (epicenter_list.length < epicenters) {
var x, y;
if (radius < 0.1) {
var retries = 100;
var done = false;
while (retries-- > 0 && !done) {
x = (Math.random() - 0.5) * 200;
y = (Math.random() - 0.5) * 200;
done = true;
epicenter_list.forEach(e => {
const distance = Math.hypot(x-e.x, y-e.y);
if (distance < 10) done = false;
});
}
} else {
const i = epicenter_list.length;
const r = radius_t * ((1-variation) + Math.sin(Math.PI * 2 * frequency / epicenters * i) * variation * 2);
x = r * Math.cos(Math.PI/2 + Math.PI * 2 / epicenters * i);
y = r * Math.sin(Math.PI/2 + Math.PI * 2 / epicenters * i);
}
epicenter_list.push({x:x, y:y, r:0.4});
}

radius_t = radius * (Math.cos(Math.PI * 2 * t) + 1) / 2;
}

const e = epicenter_list[i % epicenters];
const c = new Circle(e.x, e.y, e.r);
e.r += 1/density;

c.clip(circle_list);
if (c.lines.length > 10) {
c.draw();
circle_list.push(c);
}

return (i+1) < concentric * epicenters;
}

class Circle {
constructor(x, y, r) {
this.x = x; this.y = y; this.r = r;
this.lines = [];
const p = Math.max(3, Math.round(precision * this.r / 10));
const step = Math.PI * 2 / p;
for (var i=0; i<p; i++) {
const a0 = step * i;
const a1 = step * (i+1);
const x0 = this.x + Math.cos(a0) * this.r;
const y0 = this.y + Math.sin(a0) * this.r;
const x1 = this.x + Math.cos(a1) * this.r;
const y1 = this.y + Math.sin(a1) * this.r;
this.lines.push({start:{x:x0, y:y0}, end:{x:x1, y:y1}});
}
}

draw() {
this.lines.forEach(l => {
turtle.jump(l.start.x, l.start.y);
turtle.goto(l.end.x, l.end.y);
})
}

// This would benefit from some serious optimization
// For starters: 3 calls to hypot need to go
clip(list) {
list.forEach(c => {
if (this.x - c.x < c.r + this.r && this.y - c.y < c.r + this.r) {
const distance = Math.hypot(this.x - c.x, this.y - c.y);
if (distance < (c.r + this.r)) {
if (distance < (c.r - this.r)) {
this.lines = [];
}
const to_delete = [];
this.lines.forEach((l, i) => {
if ((Math.abs(l.start.x) > 150 || Math.abs(l.start.y) > 150) && (Math.abs(l.end.x) > 150 || Math.abs(l.end.y) > 150)) {
to_delete.unshift(i);
} else {
const d0 = Math.hypot(l.start.x - c.x, l.start.y - c.y);
const d1 = Math.hypot(l.end.x - c.x, l.end.y - c.y);
if (d0 < c.r || d1 < c.r) {
to_delete.unshift(i);
}
}
});
to_delete.forEach(i => {
this.lines.splice(i, 1);
});
}
}
});
}
}
```