
Generative Art ํน์ Coding Art์ ๊ด์ ์์ ์ฌ๊ท(Recursion)๋ ํ๋ํ์ด๋ ๋ณต์กํ ํจํด, ์ ๊ธฐ์ ์ด๊ณ ์์ฐ์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด๋ด๋ ๋ฐ ์์ด ํต์ฌ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
์ฌ๊ท ํจ์๋ ์๊ธฐ ์์ ์ ํธ์ถํ๋ ํจ์์ด๋ฉฐ, ๋ฐ๋์ ์ข ๋ฃ ์กฐ๊ฑด(Base Case)๋ฅผ ๊ฐ์ ธ์ผ ๋ฌดํ ๋ฃจํ์ ๋น ์ง์ง ์์ต๋๋ค.
๊ฐ์ฅ ๊ธฐ๋ณธ์ด ๋๋ ์ฌ๊ท ์์ ์ ๋๋ค. ํ๋์ ์ ๋ถ์ ๊ณ์ํด์ ๋ฐ์ผ๋ก ๋๋๋ฉด์ ๊ทธ๋ฆฌ๋ ์์ ์ ๋ฐ๋ณตํฉ๋๋ค.

const MAX_LEVEL = 7;
function setup() {
createCanvas(800, 450);
noLoop();
stroke(255, 200, 70);
strokeWeight(1);
}
function draw() {
background(20);
// ์ฌ๊ท ํจ์ ํธ์ถ ์์
// x1, y1, x2, y2, level
divideLine(50, height / 2, width - 50, height / 2, 0);
}
/**
* ์ ๋ถ์ ์ฌ๊ท์ ์ผ๋ก ๋๋๋ ํจ์
* @param {number} x1 ์์์ x ์ขํ
* @param {number} y1 ์์์ y ์ขํ
* @param {number} x2 ๋์ x ์ขํ
* @param {number} y2 ๋์ y ์ขํ
* @param {number} level ํ์ฌ ์ฌ๊ท ๊น์ด
*/
function divideLine(x1, y1, x2, y2, level) {
// 1. **์ข
๋ฃ ์กฐ๊ฑด (Base Case)**:
// ์ฌ๊ท ๊น์ด๊ฐ ์ต๋ ๋ ๋ฒจ์ ๋๋ฌํ๋ฉด ํจ์๋ฅผ ์ข
๋ฃํฉ๋๋ค.
if (level > MAX_LEVEL) {
return;
}
// ํ์ฌ ๋ ๋ฒจ์ ์ ๋ถ์ ๊ทธ๋ฆฝ๋๋ค.
line(x1, y1, x2, y2);
// ์ ๋ถ์ ์ค์ (Midpoint) ๊ณ์ฐ
let midX = (x1 + x2) / 2;
let midY = (y1 + y2) / 2;
// ์ค์ ์์ ์์ ์์ง์ ์ ๊ทธ๋ฆฝ๋๋ค. (์๊ฐ์ ๊ตฌ๋ถ)
let length = dist(x1, y1, x2, y2);
line(midX, midY - length * 0.3, midX, midY + length * 0.3);
// 2. **์ฌ๊ท ํธ์ถ (Recursive Call)**:
// ์๋ก์ด ๋ ๊ฐ์ ์ ๋ถ์ ๋ํด ํจ์ ์์ ์ ๋ค์ ํธ์ถํฉ๋๋ค.
// ์ผ์ชฝ ์ ๋ถ: (x1, y1) ~ (midX, midY)
divideLine(x1, y1, midX, midY, level + 1);
// ์ค๋ฅธ์ชฝ ์ ๋ถ: (midX, midY) ~ (x2, y2)
divideLine(midX, midY, x2, y2, level + 1);
}
ํ๋์ ๊ธด ์ ๋ถ ๋ฅผ ๊ทธ๋ฆฐ ํ, ์ค์ ์ ์ฐพ์ ๋ ๊ฐ์ ์ ๋ฐ ๊ธธ์ด ์ ๋ถ์ผ๋ก ๋๋๋๋ค. ์ด ๊ณผ์ ์ ๋ฏธ๋ฆฌ ์ ํด๋ MAX_LEVEL๊น์ง ๋ฐ๋ณตํฉ๋๋ค.
MAX_LEVEL: ์ฌ๊ท๊ฐ ์ผ๋ง๋ ๊น๊ฒ ์งํ๋ ์ง ๊ฒฐ์ ํ๋ ์ ํ ์ฅ์น์ ๋๋ค. ์ด๊ฒ์ด ์์ผ๋ฉด ๋ฌดํ ๋ฃจํ๊ฐ ๋ฐ์ํฉ๋๋ค.
divideLine(...): ์ฌ๊ท ์คํ์ ์ํด ์์ฑํ ํจ์์
๋๋ค. level + 1์ ์ธ์๋ก ์ ๋ฌํ์ฌ ํธ์ถ๋ ๋๋ง๋ค ๊น์ด๊ฐ ์ฆ๊ฐํฉ๋๋ค.
์ฌ๊ท๋ฅผ ์ด์ฉํ์ฌ ์์ฐ์ ํ๋ํ ๊ตฌ์กฐ๋ฅผ ํ๋ด ๋ด๋ ๋ํ์ ์ธ ์์ ์ ๋๋ค. ์ฌ๊ท ํธ์ถ๋ง๋ค ํ์ (Rotation)๊ณผ ์ถ์(Scaling)๊ฐ ์ ์ฉ๋์ด ๋ณต์กํ ๋ชจ์์ ๋ง๋ญ๋๋ค.

ํ์ ๋ผ์ธ์ผ๋ก๋ง ๋ง๋ ๊ฐ๋จํ recursive tree์ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
function setup() {
createCanvas(500, 300);
noLoop();
background(10);
stroke(220);
translate(width / 2, height);
branch(100);
}
function branch(len) {
line(0, 0, 0, -len);
translate(0, -len);
if (len > 8) {
push();
rotate(PI / 6);
branch(len * 0.67);
pop();
push();
rotate(-PI / 4);
branch(len * 0.67);
pop();
}
}
์ด๊ฑด ์ค์/์ผ/์ค๋ฅธ์ชฝ ๊ฐ์ง๋ฅผ ๋ฐ๋ก ๋ง๋๋ ๊ฐ๋จํ ์์์
๋๋ค.

// 2_recursive_tree_1
function setup() {
createCanvas(600, 600);
angleMode(DEGREES);
noLoop();
}
function draw() {
background(15);
translate(width / 2, height);
stroke(80, 150, 100);
strokeWeight(2);
drawBranch(140, 10);
}
function drawBranch(len, depth) {
// base
line(0, 0, 0, -len);
translate(0, -len);
if (depth <= 0) {
// ์
noStroke();
fill(200, 200, 200);
ellipse(0, 0, 5, 5);
stroke(20);
return;
}
// ์ผ์ชฝ ๊ฐ์ง
push();
rotate(-20 - depth * 1.5);
drawBranch(len * 0.7, depth - 1);
pop();
// ์ค๋ฅธ์ชฝ ๊ฐ์ง
push();
rotate(20 + depth * 1.5);
drawBranch(len * 0.7, depth - 1);
pop();
// ์ค์ ๊ฐ์ง : 0 ๋์ ๋ค๋ฅธ ๊ฐ์ ๋ฃ์ผ๋ฉด ์ด์ง ๋ฐฉํฅ ์ ํ
push();
rotate(map(sin(depth * 2), 0, 0, -5, 5));
drawBranch(len * 0.66, depth - 1);
pop();
// ๋์์ค๊ธฐ
translate(0, len);
}
์กฐ๊ธ ๋ ๊พธ๋ฉฐ๋ณด๋ฉด ์ด๋ ๊ฒ ํ ์๋ ์์ต๋๋ค.

// 2_recursive_tree_1
let branchLength = 100;
function setup() {
createCanvas(800, 400);
angleMode(DEGREES); // ๊ฐ๋ ๋จ์๋ฅผ degree๋ก ์ค์
stroke(10, 180, 170, 50);
strokeWeight(3);
}
function draw() {
background(25);
translate(width / 2, height); // ๊ทธ๋ฆผ์ ์์ ์ ์บ๋ฒ์ค ํ๋จ ์ค์์ผ๋ก ์ด๋
// ์ฌ๊ท ํจ์ ํธ์ถ ์์: ์ด๊ธฐ ๊ธธ์ด์ ๊น์ด
drawBranch(branchLength, 0);
}
/**
* ๊ฐ์ง๋ฅผ ์ฌ๊ท์ ์ผ๋ก ๊ทธ๋ฆฌ๋ ํจ์
* @param {number} len ํ์ฌ ๊ฐ์ง์ ๊ธธ์ด
* @param {number} level ํ์ฌ ์ฌ๊ท ๊น์ด (์ ํ ์ฌํญ์ด์ง๋ง ๋ช
์์ ์ผ๋ก ์ถ๊ฐ)
*/
function drawBranch(len, level) {
// 1. ํ์ฌ ๊ฐ์ง(์ )๋ฅผ ๊ทธ๋ฆฝ๋๋ค. (์์ (0,0)์์ ์๋ก)
line(0, 0, 0, -len);
// ์ด ์์ ์์ ์ขํ๊ณ๋ ๊ฐ์ง์ ๋์ (-len)์ผ๋ก ์ด๋ํด์ผ ํฉ๋๋ค.
translate(0, -len);
// 2. **์ข
๋ฃ ์กฐ๊ฑด (Base Case)**:
// ๊ฐ์ง์ ๊ธธ์ด๊ฐ ๋๋ฌด ์งง์์ง๋ฉด (์: 3 ํฝ์
๋ฏธ๋ง) ์ฌ๊ท๋ฅผ ๋ฉ์ถฅ๋๋ค.
if (len < 3) {
// ์์ฌ๊ท์ฒ๋ผ ์์ ์ ์ ์ฐ์ด ๋ง๋ฌด๋ฆฌ
stroke(50, 200, 50); // ๋
น์
point(0, 0);
return;
}
// 3. **์ฌ๊ท ํธ์ถ (Recursive Call)**:
// A. ์ค๋ฅธ์ชฝ ๊ฐ์ง
push(); // ํ์ฌ ์ขํ๊ณ ์ํ(์์น/ํ์ ) ์ ์ฅ
rotate(30); // 30๋ ์ค๋ฅธ์ชฝ์ผ๋ก ํ์
drawBranch(len * 0.8, level + 1); // ๊ธธ์ด 80%๋ก ์ค์ด๊ณ ์ฌ๊ท ํธ์ถ
pop(); // ์ ์ฅ๋ ์ํ๋ก ๋ณต์
// B. ์ผ์ชฝ ๊ฐ์ง
push(); // ํ์ฌ ์ขํ๊ณ ์ํ ์ ์ฅ
rotate(-55); // -65๋ ์ผ์ชฝ์ผ๋ก ํ์
drawBranch(len * 0.6, level + 1); // ๊ธธ์ด 60%๋ก ์ค์ด๊ณ ์ฌ๊ท ํธ์ถ
pop(); // ์ ์ฅ๋ ์ํ๋ก ๋ณต์
}
ํต์ฌ ์๋ ์๋ฆฌ: ๊ฐ์ง๋ฅผ ๊ทธ๋ฆฐ ํ, p5.js์ ๋ณํ ํจ์(translate, rotate, push/pop)๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ง์ ๋์ ์์ ์ขํ๊ณ๋ฅผ ํ์ ์ํค๊ณ , ๋ ์งง์ ๊ธธ์ด๋ก ๋ ๋ฒ ์ฌ๊ท ํธ์ถ์ ํฉ๋๋ค. push()์ pop()์ ๋ณต์กํ ๋ณํ์ด ์ค์ฒฉ๋ ๋ ์ขํ๊ณ๋ฅผ ์ด์ ์ํ๋ก ๋๋๋ฆฌ๋ ๋ฐ ํ์์ ์
๋๋ค.
์ฃผ์ ๋ณ์/ํจ์:
angleMode(DEGREES): ๊ฐ๋๋ฅผ ๋ค๋ฃจ๊ธฐ ์ฝ๊ฒ ๋(Degree) ๋จ์๋ก ์ค์ ํฉ๋๋ค.translate(width/2, height): ๊ทธ๋ฆผ ์์์ ์ ํ๋ฉด ํ๋จ ์ค์์ผ๋ก ์ด๋์์ผ ๋
์์ ์ฌ๋ผ์ค๋๋ก ํฉ๋๋ค.drawBranch(...): ์ฌ๊ท ํจ์๋ก, ํธ์ถ๋ ๋๋ง๋ค ๊ธธ์ด๊ฐ ์ค์ด๋ค๊ณ ํ์ ํฉ๋๋ค.push()/pop(): ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ฌ๊ท ํธ์ถ ์ ์ ํ์ฌ ์์น์ ํ์ ์ํ๋ฅผ ์ ์ฅํ๊ณ , ์ฌ๊ท ํธ์ถ์ด ๋๋ ํ ์๋ ์์น๋ก ๋์์ค๊ฒ ํฉ๋๋ค.
// ArtCode Mentor | p5.js Recursion Example 3 - Modified (Dynamic Radius Scaling)
// ๋ชฉ์ : ์ฌ๊ท ๊น์ด์ ๋ฐ๋ผ ๋ฐ์ง๋ฆ ์ถ์ ๋น์จ(Scaling Factor)๊ณผ ํฌ๋ช
๋(Alpha)๋ฅผ ๋ชจ๋ ์กฐ์
// p5.js ์ต์ ์์ ํ ๋ฒ์ ๊ธฐ๋ฐ
const START_RADIUS = 150; // ์์ ์์ ๋ฐ์ง๋ฆ
const MAX_LEVEL = 5; // ์ต๋ ์ฌ๊ท ๊น์ด ์ ํ
function setup() {
createCanvas(800, 400);
noLoop();
angleMode(DEGREES);
noStroke();
}
function draw() {
background(15);
translate(width / 2, height / 2);
// ์ฌ๊ท ํจ์ ํธ์ถ ์์ (์ค์ฌ์ , ๋ฐ์ง๋ฆ, ํ์ฌ ๊น์ด)
drawRecursiveCircles(0, 0, START_RADIUS, 1);
}
/**
* ์ฌ๊ท์ ์ผ๋ก ์์ ๊ทธ๋ฆฌ๊ณ ๊น์ด์ ๋ฐ๋ผ ์์ ํฌ๋ช
๋์ ๋ค์ ๋ฐ์ง๋ฆ ์ถ์ ๋น์จ์ ์ ์ฉํ๋ ํจ์
* @param {number} x ์ค์ฌ x ์ขํ
* @param {number} y ์ค์ฌ y ์ขํ
* @param {number} radius ํ์ฌ ์์ ๋ฐ์ง๋ฆ
* @param {number} level ํ์ฌ ์ฌ๊ท ๊น์ด (1๋ถํฐ ์์)
*/
function drawRecursiveCircles(x, y, radius, level) {
// 1. **์ข
๋ฃ ์กฐ๊ฑด (Base Case)**:
if (radius < 2 || level > MAX_LEVEL) {
// ์ต์ ๋ฐ์ง๋ฆ์ 4๋ก ์กฐ์
return;
}
// --- ์์ (ํฌ๋ช
๋๋ ์ด์ ๊ณผ ๋์ผํ๊ฒ ๊น์ด์ ๋ฐ๋ผ ์ ์ฉ) ---
// ๊น์ด๊ฐ ๊น์์๋ก ํฌ๋ช
ํด์ง๋๋ก alpha ์ค์ (255 -> 50)
let alpha = map(level, 1, MAX_LEVEL, 170, 20);
fill(10, 190, 180, alpha); // ์ฃผํฉ์ ๊ณ์ด
// ํ์ฌ ์์ ๊ทธ๋ฆฝ๋๋ค.
ellipse(x, y, radius * 2);
// --- ๋ฐ์ง๋ฆ ์ถ์ ๋น์จ ๋์ ๊ณ์ฐ ---
// ๊น์ด(level)์ ๋ฐ๋ผ ๋ค์ ๋ฐ์ง๋ฆ์ ์ถ์ ๋น์จ(Scaling Factor)์ ๊ฒฐ์ ํฉ๋๋ค.
// level 1: ์ถ์ ๋น์จ 0.35 (๋ง์ด ์ค์ด๋ฆ)
// level MAX_LEVEL: ์ถ์ ๋น์จ 0.85 (์๋์ ์ผ๋ก ์ ๊ฒ ์ค์ด๋ฆ)
let scalingFactor = map(level, 1, MAX_LEVEL, 0.5, 0.35);
// ๋ค์ ์ฌ๊ท ํธ์ถ์ ์ํ ์ ๋ฐ์ง๋ฆ
let nextRadius = radius * scalingFactor;
// --- ์ฌ๊ท ํธ์ถ ---
let angleIncrement = 60;
let offset = radius;
for (let angle = 0; angle < 360; angle += angleIncrement) {
let newX = x + cos(angle) * offset;
let newY = y + sin(angle) * offset;
// ์๋ก์ด ์์น, ๋์ ์ถ์๋ ๋ฐ์ง๋ฆ, ๊น์ด ์ฆ๊ฐ๋ก ์ฌ๊ท ํธ์ถ
drawRecursiveCircles(newX, newY, nextRadius, level + 1);
}
}
์ ๋ถ์ ๊ทธ๋ฆฌ๊ณ ์ธ๊ณฝ์์๋ถํฐ ์์ชฝ์ผ๋ก ์ ์ ๋ณ์ ๊ธธ์ด๊ฐ ์ค์ด๋ค๋ฉด์ ๊บพ์ด๋๋ก ํ๋ฉด ๊ฐ์ง ๋์ ์ด ๋ง๋ค์ด์ง๋๋ค. ๊บพ์ด๋ ๊ฐ๋๋ 360๋๋ฅผ ๊ผญ์ง์ ๊ฐ์๋ก ๋๋์ด์ ์ฝ๊ฒ ๊ตฌํ๊ณ ์ต์ด ์์ ์ ๋ถ์ ๊ธธ์ด์ ๋ง์ถ์ด์ ์์์ ์ ์ด๋์ํค๋ฉด ์ค์ ์ ๋ ฌ์ด ๊ฐ๋ฅํฉ๋๋ค. ์๋ ์ฝ๋์์๋ ์ ๋ถ์ ๊ธธ์ด๊ฐ ํน์ ๊ฐ์ด ๋๋ฉด ์ฌ๊ท๋ฅผ ๋ฉ์ถ๋ ๋ก์ง์ ๋ฃ์๊ณ , ์ธ๊ณฝ๋ถํฐ ์์ชฝ๊น์ง ์ ๋ถ์ ์ ์ฐจ ์์์ง๋๋ค.

const NUM_SIDES = 6; // ๋ค๊ฐํ์ ๊ผญ์ง์ ๊ฐ์
const START_LENGTH = 400; // ๋์ ์ ๊ฐ์ฅ ๋ฐ๊นฅ์ชฝ ๋ณ์ ์์ ๊ธธ์ด
const LENGTH_DECREMENT = 8; // ๋งค๋ฒ ๊ธธ์ด๊ฐ ์ค์ด๋๋ ๊ณ ์ ๊ฐ
const MIN_LENGTH = 2; // ๋์ ์ด ๋ฉ์ถ๋ ์ต์ ๊ธธ์ด
const MIN_WEIGHT = 0.3; // ์ ๋ถ์ ์ต์ ๋๊ป
const MAX_WEIGHT = 4 // ์ ๋ฌธ์ ์ต๋ ๋๊ป
// ์ ๋ค๊ฐํ์ ์ธ๊ฐ (External Angle) = 360๋ / ๊ผญ์ง์ ๊ฐ์
const TURN_ANGLE = 360 / NUM_SIDES;
function setup() {
createCanvas(800, 400);
noLoop();
angleMode(DEGREES); // ํ์ ์ ์ํด DEGREE ๋ชจ๋ ์ฌ์ฉ
background(5);
// ์ ๋ถ์ ๋๊ป ๋๋ฌธ์ ์บ๋ฒ์ค ๋ฐ์ผ๋ก ๋๊ฐ์ง ์๋๋ก ์์์ ์ ๋๊ป๋งํผ ์ด๋
// ์ ๋ถ์ ์์์ ์ ์ต์ด์ ๋ถ ๊ธธ์ด๋งํผ ์ด๋์์ผ์ ๋์ ์ค์ฌ์ด ์บ๋ฒ์ค ์ค์ฌ์ ์ค๋๋ก
// y์ถ์ ํ์์ ๋ฐ๋ผ ์ ์ถ๊ฐ
translate(-2 * MAX_WEIGHT + START_LENGTH / 2, MAX_WEIGHT);
// ์ฌ๊ท ํจ์ ํธ์ถ ์์ (ํ์ฌ ๊ธธ์ด, ํ์ฌ ๋จ๊ณ)
drawPolygonalSpiral(START_LENGTH, 0);
}
/**
* ๋ค๊ฐํ ๋์ ํจํด์ ์ฌ๊ท์ ์ผ๋ก ๊ทธ๋ฆฌ๋ ํจ์
* @param {number} len ํ์ฌ ์ ๋ถ์ ๊ธธ์ด
* @param {number} step ํ์ฌ ์ฌ๊ท ๋จ๊ณ (0๋ถํฐ ์์)
*/
function drawPolygonalSpiral(len, step) {
// 1. **์ข
๋ฃ ์กฐ๊ฑด (Base Case)**:
if (len <= MIN_LENGTH) {
return;
}
// 2. **์ ์คํ์ผ ์ค์ **:
// ๊น์ด์ ๋ฐ๋ผ ์ ๋๊ป์ ์์ ์ค์
let weight = map(len, MIN_LENGTH, START_LENGTH, MIN_WEIGHT, MAX_WEIGHT);
strokeWeight(weight);
stroke(60, 190, 180, 255);
// 3. **๋ค๊ฐํ ๊ทธ๋ฆฌ๊ธฐ ๋ฐ ๋ณํ**:
// N๊ฐํ ๋์ ์ N๊ฐ์ ๋ณ์ ์์๋๋ก ๊ทธ๋ฆฌ๋ฉฐ ๋์๊ฐ์ผ ํฉ๋๋ค.
// ์ฌ๊ฐํ ๋์ (N=4)์์๋ 4๊ฐ์ ๋ฐฉํฅ์ if/else if๋ก ์ฒ๋ฆฌํ์ง๋ง,
// N๊ฐํ์์๋ for ๋ฃจํ์ p5.js์ 'rotate'๋ฅผ ํ์ฉํ์ฌ ์ผ๋ฐํํฉ๋๋ค.
// ํ์ฌ ๊ธธ์ด์ ๋ฐฉํฅ์ผ๋ก ํ๋์ ๋ณ์ ๊ทธ๋ฆฝ๋๋ค.
line(0, 0, len, 0);
// ๋ค์ ๋ณ์ ๊ทธ๋ฆด ์์น๋ก ์์ ์ด๋
// (0, 0)์์ ๊ทธ๋ฆฐ ์ ๋ถ์ ๋์ (len, 0)์ผ๋ก ์ด๋ํฉ๋๋ค.
translate(len, 0);
// 4. **ํ์ (Rotation)**:
// ๋ค์ ๋ณ์ ๊ทธ๋ฆฌ๊ธฐ ์ํด ์ขํ๊ณ๋ฅผ 'TURN_ANGLE'๋งํผ ํ์ ์ํต๋๋ค.
// ์ด๋ N๊ฐํ์ ์ธ๊ฐ๋งํผ ๊บพ๋ ํจ๊ณผ๋ฅผ ์ค๋๋ค.
rotate(TURN_ANGLE);
// 5. **๊ธธ์ด ์
๋ฐ์ดํธ**:
let nextLength = len;
// ์ฌ๊ฐํ ๋์ (N=4)์์๋ 2๋จ๊ณ๋ง๋ค ๊ธธ์ด๋ฅผ ์ค์์ง๋ง,
// ์ผ๋ฐ์ ์ธ ๋ค๊ฐํ ๋์ ์์๋ ๊ฐ ๋ณ์ ๊ทธ๋ฆฐ ํ ๊ธธ์ด๋ฅผ ์ค์ด๋ ๊ฒ์ด ์์ฐ์ค๋ฝ์ต๋๋ค.
// ๊ทธ๋ฌ๋ ์๋ณธ ์ฌ๊ฐํ ๋์ ์ '๋ ๋ณ๋ง๋ค ๊ธธ์ด ๊ฐ์' ๋ก์ง์ ์ ์งํ์ฌ ๋์ ๊ตฌ์กฐ๋ฅผ ๋ง๋ญ๋๋ค.
if (step % (NUM_SIDES / 2) === 0) {
nextLength = len - LENGTH_DECREMENT;
}
// 6. **์ฌ๊ท ํธ์ถ**:
// ๊ธธ์ด๋ ์
๋ฐ์ดํธํ๋, ํ์ ๊ฐ๋๋ ๊ณ์ ๋์ ํ์ฌ ์ ์ฉํฉ๋๋ค.
drawPolygonalSpiral(nextLength, step + 1);
}