260129
const { animate } = anime;
const W = 800;
const H = 800;
const NUM_ROWS = 3;
const NUM = 20;
const TRIANGLE_SIZE = 50;
const R_SIZE = 250;
const OFFSET = 3;
const DELAY = 0.48;
let palette = [];
let animeValue = {
count: 0,
};
let rotateValue = {
count: 0,
};
function setup() {
createCanvas(W, H, WEBGL);
palette = colorArray[1].colors;
background(palette[4]);
animate(animeValue, {
count: 1,
duration: 5000,
ease: 'linear',
loop: true,
});
animate(rotateValue, {
count: 1,
duration: 2000,
ease: 'outInExpo',
loop: true,
});
}
function draw() {
background(palette[4]);
orbitControl();
push();
noStroke();
let animeCount = animeValue.count;
let rotateCount = rotateValue.count;
translate(0, -H / 2, 0);
for (let i = 0; i < NUM_ROWS; i++) {
push();
rotateY(TAU / NUM_ROWS * i);
for (let j = 0; j < NUM; j++) {
// 今の三角形の位置
let { x, y, z } = getPosition(j, i, animeCount);
// 前の三角形の位置
let jNext = (j === NUM - 1) ? j - 1 : j + 1;
let { x: xNext, y: yNext, z: zNext } = getPosition(jNext, i, animeCount);
// 前の三角形→今の三角形 の差分
let dx, dy, dz;
if (j === NUM - 1) {
dx = x - xNext;
dy = y - yNext;
dz = z - zNext;
} else {
dx = xNext - x;
dy = yNext - y;
dz = zNext - z;
}
// 回転角Y方向(垂直方向)の傾き
// dx, dzの差分から進行方向の角度
let angleY = atan2(dx, dz);
// XZ平面での2点間の距離
let horizontalLen = sqrt(dx * dx + dz * dz);
// dyとXZ平面の距離から 垂直方向の角度
let angleX = -atan2(dy, horizontalLen);
push();
translate(x, y, z);
rotateY(angleY);
rotateX(-PI / 2 + angleX);
push();
stroke(palette[6]);
push();
if (!(i === 1)) {
fill(palette[int((i + j) % (palette.length - 3))]);
} else {
fill(palette[5]);
}
translate(TRIANGLE_SIZE / 2, 0, 0);
rotateY(rotateCount * TAU + (i + j));
translate(-TRIANGLE_SIZE / 2, 0, 0);
triangle(0, 0, TRIANGLE_SIZE, 0, TRIANGLE_SIZE / 2, TRIANGLE_SIZE);
pop();
push();
if (!(i === 1)) {
fill(palette[int((i % j) % (palette.length - 3))]);
} else {
fill(palette[5]);
}
translate(TRIANGLE_SIZE / 2, 0, 0);
rotateY(rotateCount * TAU + (i + j) * DELAY);
translate(-TRIANGLE_SIZE / 2, 0, 0);
translate(0, -OFFSET, 0);
triangle(0, 0, TRIANGLE_SIZE, 0, TRIANGLE_SIZE / 2, -TRIANGLE_SIZE);
pop();
pop();
pop();
}
pop();
}
pop();
// noLoop();
}
function getPosition(idx, row, cVal) {
let theta = idx * TAU / NUM + cVal * TAU;
let y = idx * H / NUM;
let r = (!(row === 1)) ? R_SIZE : R_SIZE / 2;
if (row === 1) {
r *= cos(theta * 3);
}
let x = cos(theta) * r;
let z = sin(theta) * r;
return { x, y, z };
}
const colorArray = [
{
id: 0,
colors: ['#253276', '#dfdad3', '#ffffff', '#000000'],
},
{
id: 1,
colors: [
'#9dbdba',
'#f8b042',
'#e47763',
'#253276',
'#dfdad3',
'#FFFFFF',
'#000000',
],
},
]; Day29:Genetic evolution and mutation.
const { animate } = anime;
const W = 800;
const H = 800;
const NUM_ROWS = 3;
const NUM = 20;
const TRIANGLE_SIZE = 50;
const R_SIZE = 250;
const OFFSET = 3;
const DELAY = 0.48;
let palette = [];
let animeValue = {
count: 0,
};
let rotateValue = {
count: 0,
};
function setup() {
createCanvas(W, H, WEBGL);
palette = colorArray[1].colors;
background(palette[4]);
animate(animeValue, {
count: 1,
duration: 5000,
ease: 'linear',
loop: true,
});
animate(rotateValue, {
count: 1,
duration: 2000,
ease: 'outInExpo',
loop: true,
});
}
function draw() {
background(palette[4]);
orbitControl();
push();
noStroke();
let animeCount = animeValue.count;
let rotateCount = rotateValue.count;
translate(0, -H / 2, 0);
for (let i = 0; i < NUM_ROWS; i++) {
push();
rotateY(TAU / NUM_ROWS * i);
for (let j = 0; j < NUM; j++) {
// 今の三角形の位置
let { x, y, z } = getPosition(j, i, animeCount);
// 前の三角形の位置
let jNext = (j === NUM - 1) ? j - 1 : j + 1;
let { x: xNext, y: yNext, z: zNext } = getPosition(jNext, i, animeCount);
// 前の三角形→今の三角形 の差分
let dx, dy, dz;
if (j === NUM - 1) {
dx = x - xNext;
dy = y - yNext;
dz = z - zNext;
} else {
dx = xNext - x;
dy = yNext - y;
dz = zNext - z;
}
// 回転角Y方向(垂直方向)の傾き
// dx, dzの差分から進行方向の角度
let angleY = atan2(dx, dz);
// XZ平面での2点間の距離
let horizontalLen = sqrt(dx * dx + dz * dz);
// dyとXZ平面の距離から 垂直方向の角度
let angleX = -atan2(dy, horizontalLen);
push();
translate(x, y, z);
rotateY(angleY);
rotateX(-PI / 2 + angleX);
push();
stroke(palette[6]);
push();
if (!(i === 1)) {
fill(palette[int((i + j) % (palette.length - 3))]);
} else {
fill(palette[5]);
}
translate(TRIANGLE_SIZE / 2, 0, 0);
rotateY(rotateCount * TAU + (i + j));
translate(-TRIANGLE_SIZE / 2, 0, 0);
triangle(0, 0, TRIANGLE_SIZE, 0, TRIANGLE_SIZE / 2, TRIANGLE_SIZE);
pop();
push();
if (!(i === 1)) {
fill(palette[int((i % j) % (palette.length - 3))]);
} else {
fill(palette[5]);
}
translate(TRIANGLE_SIZE / 2, 0, 0);
rotateY(rotateCount * TAU + (i + j) * DELAY);
translate(-TRIANGLE_SIZE / 2, 0, 0);
translate(0, -OFFSET, 0);
triangle(0, 0, TRIANGLE_SIZE, 0, TRIANGLE_SIZE / 2, -TRIANGLE_SIZE);
pop();
pop();
pop();
}
pop();
}
pop();
// noLoop();
}
function getPosition(idx, row, cVal) {
let theta = idx * TAU / NUM + cVal * TAU;
let y = idx * H / NUM;
let r = (!(row === 1)) ? R_SIZE : R_SIZE / 2;
if (row === 1) {
r *= cos(theta * 3);
}
let x = cos(theta) * r;
let z = sin(theta) * r;
return { x, y, z };
}
const colorArray = [
{
id: 0,
colors: ['#253276', '#dfdad3', '#ffffff', '#000000'],
},
{
id: 1,
colors: [
'#9dbdba',
'#f8b042',
'#e47763',
'#253276',
'#dfdad3',
'#FFFFFF',
'#000000',
],
},
];