Sunburst

Sunburst effect.

Log in to post a comment.

// Adjustable parameters
const lineCount = 180; // min=60 max=360 step=10 Number of radiating lines
const rows = 8; // min=4 max=15 step=1 Number of concentric rows
const innerRadius = 100; // min=30 max=150 step=5 Radius of the inner circle
const outerRadius = 300; // min=150 max=400 step=10 Length of the radiating lines
const offsetAngle = 0.25; // min=0 max=1 step=0.05 Offset angle between rows (proportion of spacing)
const lineOpacity = 0.4; // min=0.1 max=1 step=0.1 Line opacity
const zoom = 1.0; // min=0.2 max=2.0 step=0.1 Scale the entire pattern

// Create a turtle
const turtle = new Turtle();
Canvas.setpenopacity(lineOpacity);

// Position variables
const centerX = 0;
const centerY = 0;
const angleIncrement = 2 * Math.PI / lineCount;

// Calculate non-linear spacing between rows (closer at center, wider at edges)
function getRowRadius(rowIndex) {
  // Use a quadratic function to make inner rows closer together
  const t = rowIndex / rows;
  const scaleFactor = t * t;
  return innerRadius + scaleFactor * (outerRadius - innerRadius);
}

// Line state tracking
let currentLine = 0;
let currentRow = 0;

function walk(i) {
  // Check if drawing is complete
  if (currentRow >= rows) {
    return false;
  }
  
  // Calculate current radius for this row (non-linear spacing)
  const rowRadius = getRowRadius(currentRow);
  
  // Calculate next row's radius to determine line length
  const nextRowRadius = currentRow < rows - 1 ? getRowRadius(currentRow + 1) : outerRadius;
  
  // Calculate line length (proportional to space between rows)
  const rowSpace = nextRowRadius - rowRadius;
  const lineLength = rowSpace * 0.7 * (1 + currentRow / (rows * 1.5));
  
  // Calculate angle with offset for this row
  // Each row is slightly offset from the previous one
  const rowOffset = currentRow * offsetAngle * angleIncrement;
  const angle = currentLine * angleIncrement + rowOffset;
  
  // Move to starting position
  turtle.penup();
  // Apply zoom to coordinates
  const scaledStartX = centerX + Math.cos(angle) * rowRadius * zoom;
  const scaledStartY = centerY + Math.sin(angle) * rowRadius * zoom;
  turtle.goto(scaledStartX, scaledStartY);
  
  // Draw line outward
  turtle.pendown();
  const scaledEndX = centerX + Math.cos(angle) * (rowRadius + lineLength) * zoom;
  const scaledEndY = centerY + Math.sin(angle) * (rowRadius + lineLength) * zoom;
  turtle.goto(scaledEndX, scaledEndY);
  
  // Move to next line
  currentLine++;
  
  // If we've completed all lines in this row, move to next row
  if (currentLine >= lineCount) {
    currentLine = 0;
    currentRow++;
  }
  
  // Continue drawing
  return true;
}