var nRings, thetaVariance, nSpokeMinimum, lineLength, lineOverlap, nSpokeMaximum, radiusMaximum, radiusMinimum, spokeRepetitions;
createCanvas(screenSize, screenSize);
gB = createGraphics(gBRes, gBRes);
maxDistortion = gBRes * 0.2;
nRings = ~~random(32) + 1;
thetaVariance = random(1) * random(1) * random(1);
nSpokeMinimum = ~~random(1024) + 1;
nSpokeMaximum = ~~random(1024) + 1;
radiusMinimum = random(1) * random(1) * random(1);
radiusMaximum = random(0.5) + random(1) * random(1);
spokeRepetitions = 1 + random(8) * random(1);
lineOverlap = 0.5 + random(8) * random(1);
lineLength = gBRes / lineOverlap / nRings;
gB.translate(gBRes * 0.5, gBRes * 0.5);
for (var i = 0; i <= 1; i += 1 / nRings) {
var nSpokes = map(i, 0, 1, nSpokeMinimum, nSpokeMaximum) + ~~random(8);
for (var j = 0; j <= 1; j += 1 / nSpokes) {
var theta = map(j, 0, 1, 0, spokeRepetitions * TAU) + random(thetaVariance);
var radius = map(i, 0, 1, gBRes * radiusMinimum, gBRes * radiusMaximum);
var xPos = radius * cos(theta);
var yPos = radius * sin(theta);
gB.translate(xPos, yPos);
gB.rotate(theta + PI / 2 + random(-0.125, 0.125) * random(1));
for (var k = random(-0.1, 0.1); k < 1 + random(-0.1, 0.1); k += 4 / lineLength) {
gB.stroke(0, 180 + 30 * abs(k));
gB.strokeWeight(gBRes * 0.00125 * random(0.8, 1.2));
gB.point(random(-0.1, 0.1), random(-2, 2) + k * lineLength);
image(gB, 0, 0, width, height);
screenSize = min(windowWidth, windowHeight);
function windowResized() {
resizeCanvas(screenSize, screenSize);
save(gB, 'Concentrics', 'png');
function mouseClicked() {