let ellipse_demo = function (p) {
let ellipses = [], deltas = [];
let p5canvas = p.createCanvas(600, 600);
p.textFont('Verdana'); p.textSize(13);
p.makeEllipses(nbrEllipses);
p.translate(p.width / 2, p.height / 2);
for (let i = 0; i < ellipses.length; i++)
ellipses[i].rotateBy(deltas[i]).render(p);
let time = performance.now();
let isects = []; p.fill(96); p.noStroke();
for (let i = 0; i < ellipses.length - 1; i++)
for (let j = i + 1; j < ellipses.length; j++)
isects.push(...Ellipse.intersects(ellipses[i], ellipses[j]));
time = performance.now() - time;
if (p.frameCount % 60 == 0)
calcTime = time == 0 ? '<1' : time;
for (let isect of isects)
p.ellipse(isect.x, isect.y, 6, 6);
p.fill(0, 20); p.stroke(0, 160);
p.rect(4, 4, 250, 70, 7);
p.rect(4, p.height - 26, p.width - 8, 26, 7);
p.fill(24); p.noStroke();
p.text(' [R] randomize ellipses', 10, 20);
p.text('[+/-] number of ellipses (min 3)', 10, 40);
p.text(' [P] pause/resume animation', 10, 60);
p.text(`Nbr Ellipses : ${nbrEllipses}`, 30, p.height - 10);
p.text(`Nbr Intersections : ${isects.length}`, 180, p.height - 10);
p.text(`Calculation time : ${calcTime} ms`, 400, p.height - 10);
p.keyTyped = function () {
if (animating) p.loop(); else p.noLoop();
p.makeEllipses(nbrEllipses);
if (!animating) p.redraw();
p.makeEllipses(nbrEllipses);
if (!animating) p.redraw();
p.makeEllipses(nbrEllipses);
if (!animating) p.redraw();
p.makeEllipses = function (n) {
const rndSign = () => Math.sign(Math.random() - 0.5);
const rndValue = (low, high) => low + (high - low) * Math.random();
p.colorMode(p.HSB, 360, 100, 100, 100);
for (let i = 0; i < n; i++) {
let a = ((rndValue(-0.15, 0.15) + i) * delta) % TAU;
let d = rndValue(0.2 * w, 0.35 * w);
let rx = rndValue(w / 5, w / 2.5);
let ry = rndValue(w / 20, w / 5.1);
let e = new Ellipse(d * Math.cos(a), d * Math.sin(a), rx, ry, rndValue(0, TAU));
e.attributes(p.color(hue, 100, 100, 20), p.color(hue, 100, 50, 50), 1.1);
deltas.push(rndSign() * rndValue(0.001, 0.015));
p.rotateXY = function (angle, x, y) {
let cosa = Math.cos(angle), sina = Math.sin(angle);
let nx = x * cosa - y * sina;
let ny = x * sina + y * cosa;