Chanomic Sketch

Moon's dance

Metaballの勉強。

let grid = []
let gs = [];
const D = 10;
let N, M;
let xDom, yDom;

class Gauss {
  constructor(mu, sig, ro) {
    this.mu = mu;
    this.sig = sig;
    this.ro = ro;

    this.ddmu = createVector(0, 0);
    this.dmu = createVector(0, 0);

    this.c0 = TWO_PI * this.sig.x * this.sig.y * sqrt(1 - this.ro*this.ro);
    this.c1 = -1/2*(1 - this.ro*this.ro);
  }

  func(p) {
    const X = (p.x - this.mu.x) / this.sig.x;
    const Y = (p.y - this.mu.y) / this.sig.y;
    const c2 = X*X + Y*Y - 2*this.ro*X*Y;
    return this.c0 * exp(this.c1*c2);
  }

  update() {
    this.ddmu = createVector(random(-0.01, 0.01), random(-0.01, 0.01));
    this.dmu.add(this.ddmu);
    this.mu.add(this.dmu);

    if (this.mu.x < -xDom || this.mu.x >= xDom) {
      this.dmu.x *= -0.01;
    }
    if (this.mu.y < -yDom || this.mu.y >= yDom) {
      this.dmu.y *= -0.01;
    }
  }
}

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(255);

  M = Math.floor(width / D);
  N = Math.floor(height / D);
  for (let i = 0; i < N; i++) {
    grid.push(Array.from({ length: M }).map(() => 0));
  }

  xDom = 10;
  yDom = xDom / M * N;
  gs = Array.from({ length: 10 }).map(() => {
    const mu = createVector(random(-xDom, xDom), random(-yDom, yDom));
    const s = random(0.5, 1);
    const sig = createVector(s, s);
    const ro = 0;
    return new Gauss(mu, sig, ro);
  });
}

function draw() {
  background('#252B48');
  for (let i = 0; i < N; i++) {
    for (let j = 0; j < M; j++) {
      const x = map(j, 0, M-1, -xDom, xDom);
      const y = map(i, 0, N-1, -yDom, yDom);
      let val = 0;
      for (const g of gs) {
        val += g.func(createVector(x, y));
      }
      grid[i][j] = map(val, 0, 1, 0, 255);
    }
  }

  for (let i = 0; i < N; i++) {
    for (let j = 0; j < M; j++) {
      const x = j / M * width;
      const y = i / N * height;
      let col;
      if (grid[i][j] < 0.7) col = '#252B48';
      else col = '#F7E987';

      stroke(col);
      fill(col);
      ellipse(x, y, D/4*3, D/4*3);
    }
  }

  for (const g of gs) {
    g.update();
  }
}