a single dry thistle in pen and sepia ink with one violet burst
painted by DeepSeek V4p5 2.3.2 · brush 2.2.2 · 2026-08-24
// composition: one dry thistle; the stem climbs from the bottom-left third to a crosshatched head at the left thirds crossing
// layering: ground ticks, doubled pen stem and spiky leaves, straw underwash, crosshatched involucre, radiating rotring spines, one violet wash crown last
const PALETTE = [
"#f0e9d6", // straw paper
"#c4ad74", // faded straw
"#8a7146", // sepia
"#4f4130", // dark sepia ink
"#7a5c9e", // violet, the only color
];
const HX = 272; // head centre
const HY = 292;
function chord(psi, q, ax, ay, jit) {
const h = Math.sqrt(Math.max(0, 1 - q * q)) * 0.96;
const nx = Math.cos(psi + Math.PI / 2);
const ny = Math.sin(psi + Math.PI / 2);
const tx = Math.cos(psi);
const ty = Math.sin(psi);
brush.line(
HX + ax * (q * nx - h * tx) + random(-jit, jit),
HY + ay * (q * ny - h * ty) + random(-jit, jit),
HX + ax * (q * nx + h * tx) + random(-jit, jit),
HY + ay * (q * ny + h * ty) + random(-jit, jit)
);
}
function setup() {
createCanvas(800, 800, WEBGL);
brush.scaleBrushes(2.3);
noLoop();
}
function draw() {
translate(-width / 2, -height / 2);
background("#f0e9d6");
// ground: a few dry ticks where the stem leaves the soil
brush.set("2H", "#c4ad74", 0.8);
brush.line(196, 786, 214, 776);
brush.line(262, 790, 276, 780);
brush.line(232, 796, 240, 782);
brush.line(304, 788, 296, 776);
brush.line(174, 794, 186, 788);
// the stem, doubled like a dry hollow stalk
brush.noFill();
brush.set("pen", "#4f4130", 1.05);
brush.beginShape(0.35);
brush.vertex(238 + random(-2, 2), 800);
brush.vertex(252 + random(-2, 2), 688);
brush.vertex(258 + random(-2, 2), 566);
brush.vertex(252 + random(-2, 2), 452);
brush.vertex(264 + random(-2, 2), 360);
brush.vertex(HX, HY + 40);
brush.endShape(false);
brush.set("pen", "#8a7146", 0.7);
brush.beginShape(0.35);
brush.vertex(245, 800);
brush.vertex(257, 690);
brush.vertex(263, 566);
brush.vertex(257, 450);
brush.vertex(268, 362);
brush.endShape(false);
// spiky dry leaves, drawn as jagged single lines
brush.set("pen", "#4f4130", 0.9);
brush.beginShape(0.15);
brush.vertex(253, 664);
brush.vertex(215, 650);
brush.vertex(227, 671);
brush.vertex(186, 663);
brush.vertex(199, 686);
brush.vertex(160, 683);
brush.endShape(false);
brush.beginShape(0.15);
brush.vertex(256, 556);
brush.vertex(292, 540);
brush.vertex(281, 561);
brush.vertex(318, 552);
brush.vertex(306, 574);
brush.endShape(false);
brush.set("pen", "#8a7146", 0.8);
brush.beginShape(0.15);
brush.vertex(249, 734);
brush.vertex(221, 744);
brush.vertex(233, 756);
brush.vertex(207, 764);
brush.endShape(false);
// one faint straw wash under the largest leaf
brush.noStroke();
brush.fillBleed(0.4, "out");
brush.fillTexture(0.5, 0.5);
brush.fill("#c4ad74", 42);
brush.beginShape(0.5);
brush.vertex(250, 660);
brush.vertex(190, 656);
brush.vertex(168, 682);
brush.vertex(236, 676);
brush.endShape(true);
// involucre: a faint wash, then two passes of crosshatch chords
brush.fill("#c4ad74", 55);
brush.beginShape(0.6);
brush.vertex(HX - 30, HY - 26);
brush.vertex(HX + 30, HY - 28);
brush.vertex(HX + 34, HY + 22);
brush.vertex(HX, HY + 46);
brush.vertex(HX - 33, HY + 20);
brush.endShape(true);
brush.set("rotring", "#8a7146", 0.6);
for (let q = -0.88; q <= 0.9; q += 0.17) chord(0.62, q, 35, 45, 1.6);
brush.set("rotring", "#4f4130", 0.55);
for (let q = -0.82; q <= 0.86; q += 0.21) chord(2.25, q, 35, 45, 1.6);
// bracts hooking down and out around the cup
brush.set("pen", "#4f4130", 0.7);
for (let i = 0; i < 16; i++) {
const a = Math.PI * (0.12 + 0.76 * (i / 15));
const bx = HX + Math.cos(a) * 33;
const by = HY + 8 + Math.sin(a) * 40;
const L = 14 + random(-4, 8);
brush.line(bx, by, bx + Math.cos(a + 0.25) * L, by + Math.sin(a + 0.25) * L);
}
// the burst: fine spines radiating from the head, mostly straw, a few violet
for (let i = 0; i < 56; i++) {
const a = -Math.PI / 2 + randomGaussian(0, 0.6);
const L = Math.max(26, randomGaussian(86, 24));
const r = random();
const col = r < 0.13 ? "#7a5c9e" : r < 0.58 ? "#c4ad74" : "#8a7146";
brush.set("rotring", col, random(0.45, 0.75));
const x0 = HX + Math.cos(a) * 14 + random(-4, 4);
const y0 = HY - 34 + Math.sin(a) * 10;
const mx = x0 + Math.cos(a) * L * 0.55;
const my = y0 + Math.sin(a) * L * 0.55;
const bend = random(-0.16, 0.16);
brush.beginShape(0.3);
brush.vertex(x0, y0);
brush.vertex(mx, my);
brush.vertex(mx + Math.cos(a + bend) * L * 0.45, my + Math.sin(a + bend) * L * 0.45);
brush.endShape(false);
}
// the violet crown, three pooled washes
brush.noStroke();
brush.fillBleed(0.55, "out");
brush.fillTexture(0.6, 0.6);
brush.fill("#7a5c9e", 62);
brush.circle(HX - 2 + random(-3, 3), HY - 62, 30, true);
brush.fill("#7a5c9e", 108);
brush.circle(HX + 3, HY - 68, 21, true);
brush.fill("#7a5c9e", 168);
brush.circle(HX - 1, HY - 58, 13, true);
// one spine got away
brush.set("rotring", "#8a7146", 0.5);
brush.line(356, 214, 386, 196);
brush.noStroke();
brush.fill("#7a5c9e", 120);
brush.circle(390, 192, 3.5, true);
}