Neo-Assyrian cuneiform, if you absolutely have to be anal about it
Reference images:
(mostly, Epic of Gilgamesh tablets)
penn.museum/sites/journal/550/
biblicalarchaeology.…-gilgamesh-epic-.jpg
britishmuseum.org/collection/object/w_k-3375
pixels.com/featured/…on-westmoreland.html
Log in to post a comment.
const seed = 4536; // min=1, max=10000, step=1
const symbol_h = 6; // min=4, max=12, step=1
const tablet = 1; // min=0, max=1, step=1 (full screen, broken tablet)
const n_columns = 2; // min=1, max=3, step=1
Canvas.setpenopacity(1);
const t = new Turtle();
let cur_rand = seed;
function rand_int() { cur_rand = (cur_rand * 48271) % (2**31 - 1); return cur_rand; }
function rand_bool() { return rand_int() % 2 == 0; }
function rand_float() { return rand_int() / (2**31 - 1); }
function draw_arc(x1, y1, x2, y2, deg) {
let rad = deg * Math.PI / 180;
let dx = x2 - x1, dy = y2 - y1;
let phi = Math.atan2(dy, dx);
let d = Math.sqrt(dx * dx + dy * dy);
let rot = (phi * 180 / Math.PI) - (180 - deg/2) ;
let r = (d / 2) / Math.sin(rad/2);
t.jump(x1, y1);
t.seth(rot);
t.circle(r, -deg);
}
function draw_wedge(x, y, w, h, stem, rotate) {
let rot = rotate * Math.PI / 180;
let h1 = stem ? h/3 : h;
let x1 = x - w/2 * Math.cos(rot), y1 = y - w/2 * Math.sin(rot);
let x2 = x + h1 * Math.sin(rot), y2 = y - h1 * Math.cos(rot);
let x3 = x + w/2 * Math.cos(rot), y3 = y + w/2 * Math.sin(rot);
let x4 = x + h * Math.sin(rot), y4 = y - h * Math.cos(rot);
draw_arc(x1, y1, x2, y2, 90);
draw_arc(x2, y2, x3, y3, 45);
draw_arc(x3, y3, x1, y1, 45);
if (stem) {
t.jump(x2, y2);
t.goto(x4, y4);
}
}
const N_types = 6;
function draw_symbol(x, y, h, type, max_w=200) {
var W;
switch (type) {
case 0: // vert 1 row
let n0 = 1 + rand_int() % 4;
W = n0 * h/3;
if (W <= max_w) {
for (let i = 0; i < n0; i++) {
draw_wedge(x + h/3 * i, y, h/3, h, true, 180);
}
}
break;
case 1: // hor 1 row
W = h;
if (W <= max_w) {
let n1 = 1 + rand_int() % 3;
for (let i = 0; i < n1; i++) {
draw_wedge(x, y + h/(n1 + 1) * (i + 1), h/3, h, true, 90);
}
}
break;
case 2: // hor 1 row + vert 1 row
W = h;
if (W <= max_w) {
let n21 = 1 + rand_int() % 3;
for (let i = 0; i < n21; i++) {
draw_wedge(x, y + h/(n21 + 1) * (i + 1), h/3, h, true, 90);
}
let n20 = 1 + rand_int() % 2;
for (let i = 0; i < n20; i++) {
draw_wedge(x + h/3 + h*2/3/(n20 + 1) * (i + 1), y, h/3, h, true, 180);
}
}
break;
case 3: // vert 2 rows
let n31 = 1 + rand_int() % 4;
let n32 = 1 + rand_int() % 4;
let n3 = Math.max(n31, n32);
W = n3 * h/3;
if (W <= max_w)
{
for (let i = 0; i < n31; i++) {
draw_wedge(x + h/3 * n3 / (n31 + 1) * (i + 1), y + h/3 - h/6, h/3, h/3, false, 180);
}
for (let i = 0; i < n32; i++) {
draw_wedge(x + h/3 * n3 / (n32 + 1) * (i + 1), y + 2*h/3 - h/6, h/3, h/3, false, 180);
}
}
break;
case 4: // hor 2 rows
W = 2 * h/3;
if (W <= max_w) {
let n41 = 1 + rand_int() % 4;
let n42 = 1 + rand_int() % 4;
let n4 = Math.max(n41, n42);
for (let i = 0; i < n41; i++) {
draw_wedge(x, y + h/3 * n4 / (n41 + 1) * (i + 1), h/3, h/3, false, 90);
}
for (let i = 0; i < n42; i++) {
draw_wedge(x + h/3, y + h/3 * n4 / (n42 + 1) * (i + 1), h/3, h/3, false, 90);
}
}
break;
case 5: // blank
if (rand_float() < 0.15) {
W = h * (1 + 2.5 * rand_float());
}
else {
W = 0;
}
break;
default:
W = 0;
}
return W;
}
let x_left = [];
for (let y = 0; y <= 200; y++) {
x_left[y] = -100;
}
let frame = 5;
if (tablet == 1) {
for (let y = 0; y <= 200; y++) {
x_left[y] += frame;
}
var x1, y1, x2, y2;
let corner = rand_int() % 2;
switch (corner) {
case 0:
x1 = -100 + frame;
y1 = -100 + frame + 20 + 40 * rand_float();
x2 = -100 + frame + 60 + 80 * rand_float();
y2 = -100 + frame;
t.jump(x2, y2);
t.goto(+100 - frame, -100 + frame);
t.goto(+100 - frame, +100 - frame);
t.goto(-100 + frame, +100 - frame);
t.goto(x1, y1);
break;
case 1:
x1 = -100 + frame;
y1 = +100 - frame - 20 - 40 * rand_float();
x2 = -100 + frame + 60 + 80 * rand_float();
y2 = +100 - frame;
t.jump(x1, y1);
t.goto(-100 + frame, -100 + frame);
t.goto(+100 - frame, -100 + frame);
t.goto(+100 - frame, +100 - frame);
t.goto(x2, y2);
break;
}
stack = [];
stack.push([x1, y1, x2, y2]);
while (stack.length > 0) {
var sx1, sy1, sx2, sy2;
[sx1, sy1, sx2, sy2] = stack.pop();
if ((Math.abs(sy1 - sy2) < 0.5) && (Math.abs(sx1 - sx2) < 0.5)) {
let ymin = Math.floor(Math.min(sy1, sy2)) + 100;
x_left[ymin] = Math.max(x_left[ymin], sx1, sx2);
t.jump(sx1, sy1);
t.goto(sx2, sy2)
}
else {
let cy = (sy1 + sy2) / 2;
let cx = (sx1 + sx2) / 2 + Math.abs(sx1 - sx2) * 0.2 * (1 - 2 * rand_float());
stack.push([sx1, sy1, cx, cy]);
stack.push([cx, cy, sx2, sy2]);
}
}
}
let h = symbol_h;
let gap_h = h/4;
let gap_v = h/10;
let gap_c = h;
let H = Math.floor((200 - 2 * frame) / (h + gap_h));
let prev_type = -1;
let prev_w = -1;
for (let y = 0; y < H; y++) {
let y0 = -100 + gap_h + y * (h + gap_h) + frame;
for (let c = 0; c < n_columns; c++) {
let x0 = -100 + (200 - gap_c * (n_columns - 1)) / n_columns * c + gap_c * c;
let x1 = x0 + (200 - gap_c * (n_columns - 1)) / n_columns;
x0 = Math.max(x0, x_left[Math.floor(y0) + 100] + gap_h, x_left[Math.floor(y0 + h + gap_h) + 100] + gap_h);
if (tablet == 1) {
x1 = Math.min(x1, 100 - frame);
}
while (x0 < x1) {
let type = rand_int() % N_types;
if (type == prev_type) {
type = (type + 1 + N_types) % N_types;
}
let max_w = x1 - x0;
prev_w = draw_symbol(x0, y0, h, type, max_w);
if (type != 5) { // not blank
prev_type = type;
}
x0 += prev_w
if (prev_w != 0) {
x0 += gap_h
}
}
}
}