1. The base radius
let baseRadiusVariation = random(1 - config.radiusVariation, 1 + config.radiusVariation);
let r_base = config.initialRadius * pow(config.growthRate, layerIndex) * baseRadiusVariation;
2. The stroke properties and shape generation
let thickness = random(config.strokeWeightMin, config.strokeWeightMax);
strokeWeight(thickness);
stroke(hue(interColor), saturation(interColor), brightness(interColor), config.alpha);
let currentNoiseMagnitude = r_base * config.noiseMagnitudeFactor * lerp(0.5, 1.5, t_norm);
beginShape();
vertex(umboX, umboY)
for (let ang = startAngle; ang <= endAngle; ang += config.angleStep) {
let ang_norm_across_arc = map(ang, startAngle, endAngle, 0, 1);
let lobeDeformation = sin(ang_norm_across_arc * config.numLobesOnEdge * 180) * currentNoiseMagnitude * 0.5;
let perlinDeformation = (noise(ang_norm_across_arc * 5, layerIndex * config.noiseSmoothness) - 0.5) * currentNoiseMagnitude;
let totalDeformation = lobeDeformation + perlinDeformation;
let radiusWithDeformation = r_base + totalDeformation;
let x = umboX + radiusWithDeformation * config.shellWidthFactor * cos(ang);
let y = umboY + radiusWithDeformation * sin(ang);
vertex(x, y);
}
endShape(CLOSE);
3. The angle calculation
let startAngle = config.angleOffset - config.arcAperture / 2;
let endAngle = config.angleOffset + config.arcAperture / 2;