constructor (x, y, r, dir = null) {
this.pos = createVector(x,y);
this.dir = createVector(speed,0);
this.dir.rotate(random(TWO_PI))
this.dir.rotate(random( ...directionJitter))
let x = constrain (this.pos.x, r, width-r)
let y = constrain (this.pos.y, r, height-r)
if (x != this.pos.x || y != this.pos.y) {
this.dir.rotate(random(TWO_PI))
return dist(cx,cy,this.pos.x,this.pos.y) <= r+this.r
let d = this.pos.dist(other.pos);
let td = this.r + other.r;
let pen = this.penetration(other);
if (abs (pen) < minR*touchRatio) {
this.dir.rotate(radians(0.1))
let v =this.pos.copy().sub(other.pos).setMag(speed);
circle (this.pos.x, this.pos.y, this.r*2)
let q = p.copy().add(this.dir.copy().setMag(this.r));
line (p.x, p.y, q.x, q.y)
let creationSpread = 0.8;
let directionJitter = [0, 0.05];
let circleAreaRatio = 20;
function randomElement () {
let dir = createVector(1, 0);
dir.rotate(random(TWO_PI));
let v = dir.copy().mult(random(R*creationSpread))
v.add(createVector(centerX, centerY));
return new E1(v.x, v.y, random(minR,maxR), dir.mult(speed));
createCanvas(windowWidth, windowHeight);
R = min(width,height) / 2;
n = floor(random(100,400));
circleAreaRatio = random(2,30);
let avgCircleArea = area / n;
let minCircleArea = 2 * avgCircleArea / (circleAreaRatio+1);
minR = sqrt(minCircleArea)/PI;
maxR = sqrt(minCircleArea*circleAreaRatio)/PI;
for (let i = 0; i < n; i++) {
elements.push (randomElement());
function mouseClicked() {
if (mode == "elements") {
if (mode == "elements") renderElements()
function renderElements() {
for (let e of elements) e.draw()
function renderPicture () {
for (let i = 0; i < n; i++) {
for (let j = i+1; j < n; j++) {
if (abs(a.penetration(b)) < minR * drawRatio) {
stroke(map ((a.r+b.r)**colorRatioPwr,
(2*maxR)**colorRatioPwr, 0, 255),20)
line (a.pos.x, a.pos.y, b.pos.x, b.pos.y)
for (let e of elements) {
if (e.inCircle(centerX, centerY, R))
newElements.push (randomElement())
for (let i = 0; i < n; i++) {
for (let j = i+1; j < n; j++) {