0x1d0171d9…aa9asent to0x99a9b7c1…b069·#16,157,796·view on Etherscan
tte_names.indexOf(_C.palette)];
/*************************************************************************/
/*************************************************************************
* Background color and grid.
*************************************************************************/
background(white);
bg_cfg = create_grid_background(mrgn = 0, {style: bg_style_names.indexOf(_C.bg_style)});
rnd = new Random(seed);
/*************************************************************************/
/*************************************************************************
* Style-specific options.
*************************************************************************/
sshape = rnd.random_choice(["rect", "ellipse"]);
num_elements = 100000;
strokeWeight(w / 600);
y_offsets = {};
op_layers = {};
patch_factor = rnd.random_choice([w / 30, w / 20]);
/*************************************************************************/
console.log(_C);
noLoop();
}
function draw() {
/*************************************************************************
* Let's draw!
*************************************************************************/
for (var n = 0; n < num_elements; n++) {
let x = rnd.random_num(0, w), y = rnd.random_num(0, h);
// y = n/num_elements*h;
if (_C.reflection == "yes") {
if (y > 2*h/3) {
ysend = y-2*h/3;
ysend = ysend*3;
ysend = h-ysend;
} else {
ysend = y/(2*h/3)*h;
}
} else {
ysend = y;
}
let use_color_gen = get_color_for_location(x, ysend, Nx, Ny, color_pattern, mask_gen, use_colors, _C.texture == "gradient", noise_vector) // samples the color to be used at a location
let use_color = use_color_gen[0], gen = use_color_gen[1];
if (_C.texture == "gradient") {
let use_color_hsv = rgb2hsv(use_color[0], use_color[1], use_color[2]);
//TODO: Target colors are just one of 4. Don't need to convert them to HSV for each pixel separately. Convert once and then use.
let target_color = use_colors[color_pattern[gen]], target_color_hsv = rgb2hsv(target_color[0], target_color[1], target_color[2]);
// Hue directly set to the target hue. Not affected by xy2rgb.
use_color_hsv[0] = target_color_hsv[0];
// Value directly set to the target hue. Not affected by xy2rgb.
use_color_hsv[2] = target_color_hsv[2];
use_color = hsv2rgb(use_color_hsv[0], use_color_hsv[1], use_color_hsv[2])
}
place_mark(x, y, use_color)
}
/*************************************************************************/
// Sanity check seed value across resolutions after everything's done.
console.log(rnd.random_dec());
/*************************************************************************
* Grains
*************************************************************************/
for (let i = 0; i < 20000; i++) {
let x = margin + rnd.random_dec() * (w - 2 * margin),
y = margin + rnd.random_dec() * (h - 2 * margin);
let clr = [white[0], white[1], white[2], rnd.random_dec() * 0.2 * 255];
stroke(clr);
fill(clr);
circle(x, y, rnd.random_dec() * pt / 2);
}
bg_cfg.clr = bg_white_stroke;
create_grid_background(mrgn=0, bg_cfg);
/*************************************************************************/
duration = Date.now() - start;
console.log(duration, "ms")
// saveCanvas(tokenData.hash.toString() + '_' + _C.bg_style.toString() + '_' + _C.category.toString() + '_' + _C.color_style.toString() + '_' + _C.palette_idx.toString() + '_' + _C.reflection.toString() + '_' + _C.use_xy2rgb.toString(), 'png')
}
function place_mark(x, y, use_color) {
// Don't draw in the margins.
if (x < margin || x > w - margin || y < margin || y > h - margin) return;
if (op_layers.hasOwnProperty(int(x / patch_factor)) == false)
op_layers[int(x / patch_factor)] = rnd.random_dec() * 128 * (x - margin) / (w - 2 * margin);
else rnd.random_dec();
use_color = rgb2hsv(use_color[0], use_color[1], use_color[2]);
use_color[2] = (0.96 + 0.04 * (x - margin) / (w - 2 * margin)) * use_color[2];
use_color = hsv2rgb(use_color[0], use_color[1], use_color[2]);
use_color.push(128 + op_layers[int(x / patch_factor)]);
fill(use_color); stroke(use_color);
if (y_offsets.hasOwnProperty(int(x / patch_factor)) == false)
y_offsets[int(x / patch_factor)] = rnd.random_choice([-1, 1]) * rnd.random_dec();
else rnd.random_choice([-1, 1]) * rnd.random_dec();
if (sshape == "rect")
rect(x, y_offsets[int(x / patch_factor)] * (h / 100) + y, rnd.random_choice([w / 150, w / 125, w / 100]), rnd.random_choice([w / 100, w / 75, w / 50]));
else if (sshape == "ellipse")
ellipse(x, y_offsets[int(x / patch_factor)] * (h / 100) + y, rnd.random_choice([w / 150, w / 125, w / 100]), rnd.random_choice([w / 100, w / 75, w / 50]));
}
function get_color_for_location_xy2rgb(x, y, noise_vector, precision) {
x = x - w / 2;
x = x / w;
y = y - h / 2;
y = y / h;
F = [y, x]; // model was trained to take row (i.e., y) as the first feature
for (var n = 0; n < min_noise.length; n++) {
F.push(noise_vector[n])
}
for (var L = 0; L < Weights.length; L++) {
W = Weights[L];
B = Bias[L];
if (L == Weights.length - 1) {
is_relu = false;
} else {
is_relu = true;
}
A = get_activations(F, W, B, is_relu, precision);
F = A;
}
use_color = A;
for (var m = 0; m < 3; m++) {
if (use_color[m] < 0) {
use_color[m] = 0
}
if (use_color[m] > 1) {
use_color[m] = 1
}
use_color[m] = Math.round(use_color[m] * 255);
}
return use_color;
}
function get_activations(F, W, B, is_relu, precision) {
A = new Array();
for (var j = 0; j < W.length; j++) {
A[j] = B[j];
// Borrowed from https://github.com/photopea/UNN.js/blob/master/UNN.js#L22.
let l = W[j].length,
k = 0;
while (((l - k) & 3) != 0)
A[j] += F[k] * W[j][k++];
for (; k < l; k += 4)
A[j] += F[k] * W[j][k] + F[k + 1] * W[j][k + 1] + F[k + 2] * W[j][k + 2] + F[k + 3] * W[j][k + 3];
A[j] = A[j] / precision;
if (is_relu) {
if (A[j] < 0) {
A[j] = 0
}
}
}
return A
}
function get_color_for_location(c, r, Nx, Ny, color_pattern, mask_gen, use_colors, use_xy2rgb, noise_vector) {
// does bilinear interpolation on mask_gen (which is 10x10 maps for 4 colors) to figure out distribution over the 4 colors at any (x,y) location. Then argmax, or average, or sample from the distribution. Need to do this right based on the quadrant to get the symmetries I mentioned.
let cuse = ((c - margin) / (w - 2 * margin) * (Nx - 1)),
ruse = ((r - margin) / (h - 2 * margin) * (Ny - 1)),
ca = cuse - floor(cuse),
ra = ruse - floor(ruse);
// getting the to-left, top-right, etc. co-ordinates to use as anchors for bilinear interpolation
let ptl = new Array;
for (var k = 0; k < pattern.length; k++) {
ptl[k] = mask_gen[k][max(0, floor(cuse))][max(0, floor(ruse))];
}
let ptr = new Array;
for (var k = 0; k < pattern.length; k++) {
ptr[k] = mask_gen[k][min(9, ceil(cuse))][max(0, floor(ruse))];
}
let pbl = new Array;
for (var k = 0; k < pattern.length; k++) {
pbl[k] = mask_gen[k][max(0, floor(cuse))][min(9, ceil(ruse))];
}
let pbr = new Array;
for (var k = 0; k < pattern.length; k++) {
pbr[k] = mask_gen[k][min(9, ceil(cuse))][min(9, ceil(ruse))];
}
// interpolation
let p = new Array;
for (var k = 0; k < pattern.length; k++) {
p[k] = (1 - ca) * (1 - ra) * ptl[k] + (ca) * (1 - ra) * ptr[k] + (1 - ca) * (ra) * pbl[k] + (ca) * (ra) * pbr[k];
}
// max
let gen = p.indexOf(max(p));
if (use_xy2rgb == true) {
use_color = get_color_for_location_xy2rgb(c, r, noise_vector[gen], precision)
} else {
use_color = use_colors[color_pattern[gen]];
}
return [use_color, gen];
}
function reshape(vector, R, C) {
var i = 0;
var grid = new Array()
for (var c = 0; c < C; c++) {
grid[c] = new Array()
for (var r = 0; r < R; r++) {
grid[c][r] = vector[i];
i = i + 1;
}
}
return grid;
}
function create_grid_background(mrgn = 0, cfg = {}) {
wh = h - 2 * mrgn, ww = w - 2 * mrgn; // working height, width
if ("clr" in cfg == false) cfg.clr = bg_black_stroke;
noStroke(); fill(cfg.clr);
if ("style" in cfg == false) cfg.style = rnd.random_choice([0, 1, 2, 3]);
if (cfg.style == 0) { // graph
if ("gap" in cfg == false) cfg.gap = ww / rnd.random_choice([20, 30, 50]);
for (let i = mrgn; i <= mrgn + ww; i += cfg.gap) {
y_start = mrgn;
for (let y_start = mrgn; y_start <= mrgn + wh; y_start += pt / 2) {
if (rnd.random_dec() < 0.5) ellipse(i, y_start, pt * (1 + 0.5 * rnd.random_dec()));
}
}
for (let i = mrgn; i <= mrgn + wh; i += cfg.gap) {
for (let x_start = mrgn; x_start < mrgn + ww; x_start += pt / 2) {
if (rnd.random_dec() < 0.5) ellipse(x_start, i, pt * (1 + 0.5 * rnd.random_dec()));
}
}
} else if (cfg.style == 1) { // threads
for (let i = 0; i < 1000; i++) {
let xstart = mrgn + rnd.random_dec() * ww,
ystart = mrgn + rnd.random_dec() * wh,
angle = rnd.random_dec() * 2 * Math.PI,
len = pt * 10 * (1 + rnd.random_dec());
for (let j = 0; j < 1; j += 0.035) {
if (rnd.random_dec() < 0.5) {
ellipse(xstart + j * Math.cos(angle) * len, ystart + j * Math.sin(angle) * len, pt * (1 + rnd.r