xxxxxxxxxx
240
p5.disableFriendlyErrors = true;
let dim = 517;
let m1, m2;
let msX, msY;
let rotationAlpha = 0;
let rotationIter;
function setup() {
cnvs = createCanvas(dim, dim/2);
background(255);
/* x, y, dim, sc,
n1, n2, td, v1, v2, b1, b2,
l1, l2, c1, c2, t1, t2,
core, circ, blob, line, tipx */
m1 = new Mutation(0, 0, dim/2, 0.3,
29, 29, 1, 0, 10, 0, 0,
0, 70, 10, 10, 0, 20,
false, false, true, true, false, 1);
m2 = new Mutation(dim/2, 0, dim/2, 0,
1, 12, 1, 0, 10, 0, 0,
0, 60, 10, 10, 0, 10,
false, false, true, true, false, 2);
}
function draw() {
background(255);
msX = ((mouseX > 0) & (mouseX <= width)) ?
mouseX : width * 0.7;
msY = ((mouseY > 0) & (mouseY <= height)) ?
mouseY : height/2;
m1.update();
m2.update();
stroke("#ffb901");
strokeWeight(1.5);
noFill();
let w2 = width/2, h2 = height-2, ad = 40;
let ver = {
x1: w2,
y1: h2,
x2: w2,
y2: map(msY, 0, h2, h2 - ad, h2)
};
let hor = {
x1: w2,
y1: h2,
x2: map(msX, 0, 2*w2, w2 - ad, w2 + ad),
y2: h2
};
line(ver.x1, ver.y1, ver.x2, ver.y2);
line(hor.x1, hor.y1, hor.x2, hor.y2);
}
class Mutation {
constructor(x, y, dim, sc, n1, n2, td, v1, v2, b1, b2, l1, l2,
c1, c2, t1, t2, core, circ, blob, line, tipx, intv) {
this.dim = dim;
this.width = dim;
this.height = dim;
this.rttAlpha = random(0, TWO_PI);
this.amp = random(0.01, 1);
this.core = core;
this.circ = circ;
this.blob = blob;
this.line = line;
this.tipInside = tipx;
this.pos = { "x": x, "y": y };
this.rayMax = int(n2 + 2);
this.seeds = [];
this.rays = [];
this.rtt = 0;
this.interactiveVersion = intv;
this.circleSize = new NoiseSeed(dim*sc, dim, 0.03);
this.coreSize = new NoiseSeed(c1, c2, 0.06)
this.rayCount = new NoiseSeed(n1, n2, 0.01);
this.tipDistr = new NoiseSeed(1, td);
this.strokeW = new NoiseSeed(2, 4, 0.05);
this.strokeW2 = new NoiseSeed(1, 2, 0.05);
this.seeds = [this.circleSize, this.coreSize, this.rayCount,
this.tipDistr, this.strokeW, this.strokeW2];
for (let r = 0; r < this.rayMax; r++) {
let ray = {
"valley": new NoiseSeed(v1, v2, random(0.01, 0.07)),
"begin": new NoiseSeed(b1, b2, random(0.001, 0.07)),
"length": new NoiseSeed(l1, l2, random(0.001, 0.07)),
"tip": new NoiseSeed(t1, t2, random(0.001, 0.07))
}
this.seeds.push(ray.valley, ray.begin,
ray.length, ray.tip);
this.rays.push(ray);
}
}
update() {
this.seeds.forEach(function(s) {
s.update();
});
this.rtt += 0.005;
let cr = this.circleSize.value() * 0.3;
let rc = this.rayCount.intValue();
let coef1 = 0;
let coef2 = 0;
if (this.interactiveVersion === 1) {
cr = map(msX, 0, dim, -height * 0.3, height * 0.3);
rc = int(map(msY, 0, height, 2, this.rayMax-2));
} else if (this.interactiveVersion === 2) {
coef1 = map(msX, 0, dim, -80, 50);
coef2 = map(msY, 0, height, 0, 60);
}
push();
translate(this.pos.x + this.width/2,
this.pos.y + this.height/2);
noFill();
stroke(0);
strokeWeight(this.strokeW2.value());
if (this.core === true) {
circle(0, 0, this.coreSize.value());
} else if (this.circ === true) {
circle(0, 0, cr * 2);
}
push();
rotate(this.rtt);
strokeWeight(this.strokeW2.value());
// Rays and Tips
for (let i = 0; i < rc; i++) {
let r1 = cr - this.rays[i].begin.value();
let r2 = cr + this.rays[i].length.value();
let alpha = i * (TWO_PI / rc);
alpha += this.rttAlpha;
let x1 = r1 * Math.cos(alpha);
let y1 = r1 * Math.sin(alpha);
let x2 = r2 * Math.cos(alpha);
let y2 = r2 * Math.sin(alpha);
if (this.line) {
line(x1, y1, x2, y2);
}
let circX = x2, circY = y2;
if (this.tipInside) {
circX = x1;
circY = y1;
}
if (i % this.tipDistr.intValue() === 0) {
circle(circX, circY, this.rays[i].tip.value() + coef2);
}
}
// Bezier Star
if (this.blob) {
curveTightness(0);
beginShape();
let angle = TWO_PI / rc;
let index = 0;
for (let a = 0; a <= TWO_PI + angle; a += angle) {
let alpha = a + this.rttAlpha;
let r1 = cr - this.rays[index].valley.value() - coef1;
let r2 = cr; // + this.rays[index].length.value();
let vrtxOut = {
"x": Math.cos(alpha) * r2,
"y": Math.sin(alpha) * r2
}, vrtxIn = {
"x": Math.cos(alpha + angle/2.0) * r1,
"y": Math.sin(alpha + angle/2.0) * r1
};
index++;
if (a != 0) curveVertex(vrtxOut.x, vrtxOut.y);
curveVertex(vrtxIn.x, vrtxIn.y);
}
endShape();
}
pop();
pop();
}
}
class NoiseSeed {
constructor(min, max, speed = 0.01) {
this.min = min;
this.max = max;
this.speed = speed;
this.seed = random(0, 1000);
}
update() {
if (frameCount === 31) {
this.speed = -this.speed;
}
this.seed += this.speed;
}
value() {
return map(noise(this.seed), 0, 1, this.min, this.max);
}
intValue() {
return int(this.value());
}
}
function mousePressed() {
let timestamp = (new Date()).toUTCString();
let f = "2020mutations - " + timestamp;
saveCanvas(cnvs, f, 'png');
}