Media Art ProgrammingWeek 03 · Period 02 Handout

p5.js / Media Art Programming

3주차 2교시 — for 반복문과 패턴

Color and Repetition 주제의 학생용 강의 자료입니다.

WEEK 03 PERIOD 02 P5.JS MEDIA ART

3주차 2교시 — for 반복문과 패턴

강의 아웃라인: week-03-outline 이전 교시: week-03-period1-student (색상 체계: RGB, HSB, 투명도) 다음 교시: week-03-period3-student (학생 주도 실습: 기하학적 패턴 아트)

항목 내용
대상 P5.js 입문자 (테크아트 전공)
소요 시간 45분
사전 준비 1교시 색상 체계 (RGB / HSB / alpha)
학습 목표
  • for 반복문의 구조를 이해하고 반복 변수 i를 활용할 수 있습니다
  • 반복문으로 도형을 패턴으로 배열할 수 있습니다
  • 반복문과 색상(RGB/HSB)을 결합해 그라데이션·무지개 패턴을 만들 수 있습니다

1교시 복습

1교시에서 색상을 자유롭게 다루는 법을 배웠습니다. 두 가지를 짚고 갑니다.

색이 아무리 예뻐도 도형을 하나하나 손으로 그려야 한다면 작품을 만들기 어렵습니다. 2교시에서는 같은 코드를 수백 번 반복하는 법을 배워서, 도형을 여러 개 배치합니다.


심화 개념 1 — 왜 반복문이 필요한가?

원 10개를 가로로 한 줄 나열한다고 합시다.

방법 A: 하나씩 직접 쓰기

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();
  fill(100, 150, 255);

  ellipse(20, 200, 30, 30);
  ellipse(60, 200, 30, 30);
  ellipse(100, 200, 30, 30);
  ellipse(140, 200, 30, 30);
  ellipse(180, 200, 30, 30);
  ellipse(220, 200, 30, 30);
  ellipse(260, 200, 30, 30);
  ellipse(300, 200, 30, 30);
  ellipse(340, 200, 30, 30);
  ellipse(380, 200, 30, 30);
}

10줄입니다. 100개를 그리려면 100줄, 1000개면 현실적으로 어렵습니다.

방법 B: for 반복문 사용

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();
  fill(100, 150, 255);

  for (let i = 0; i < 10; i++) {
    ellipse(i * 40 + 20, 200, 30, 30);
  }
}

3줄입니다. 결과는 똑같습니다. 100개를 그리려면 10100으로 바꾸면 끝입니다. 프로그래밍의 핵심은 반복되는 패턴을 찾아서 자동화하는 것입니다. 위에서 반복된 건 ellipse(?, 200, 30, 30) — x좌표만 40씩 증가하는 패턴입니다.

반복문의 핵심 장점: 수정이 쉬워진다

코드가 짧아지는 것만이 장점이 아닙니다. 수정이 한 곳에서 해결된다는 점이 핵심 장점입니다.

방식 ‘원 크기를 30→50’ 수정할 곳
방법 A (복사-붙여넣기) 10줄 각각 수정 — 하나라도 빠뜨리면 버그
방법 B (for문) 1곳만 수정 — 3050으로

i < 10i < 100으로 숫자 하나만 바꾸면 원이 100개가 됩니다. 이것이 반복문의 힘입니다.


심화 개념 2 — for 반복문 기본 문법

구조 분해

for (let i = 0; i < 10; i++)
     ─────────  ──────  ───
        ①         ②     ③
부분 코드 의미 비유
① 초기화 let i = 0 시작값 설정 “0번부터 시작!”
② 조건 i < 10 언제까지 반복? “10번 미만까지!”
③ 증가 i++ 매 반복 후 +1 “한 번 끝나면 다음!”

i++i = i + 1의 줄임말입니다. 매 반복이 끝날 때마다 i가 1씩 증가합니다.

실행 흐름 추적

function setup() {
  createCanvas(400, 400);

  for (let i = 0; i < 5; i++) {
    console.log("i의 값:", i);
  }
}

콘솔 출력:

i의 값: 0
i의 값: 1
i의 값: 2
i의 값: 3
i의 값: 4

i=0 → 조건 확인(0 < 5? 네) → 실행 → i++ → i=1 → … → i=5 → 조건 확인(5 < 5? 아니오) → 종료.

주의

i는 0부터 시작해서 4까지입니다. 5가 아닙니다. i < 5니까 5가 되는 순간 멈춥니다.

05 for loop execution flow

2주차 변수와의 연결

2주차에서 let faceX = mouseX;로 변수를 만들었습니다. for문의 ilet으로 만든 변수입니다.

2주차 변수 for문의 i
선언 let faceX = mouseX; let i = 0;
값 변화 직접 대입 매 반복마다 자동 +1
용도 좌표 저장 반복 횟수 세기 + 활용
확인 질문

for (let i = 0; i < 3; i++)이면 i는 몇 번 반복하고, 마지막 i 값은 뭘까요?

: 3번 반복 (i=0, 1, 2), 마지막 i 값은 2.

증가값 바꾸기: i++ 말고 다른 것도 가능

i++는 1씩 증가하는 것인데, 2씩·3씩도 가능합니다.

function setup() {
  createCanvas(400, 400);

  // 2씩 증가
  for (let i = 0; i < 10; i += 2) {
    console.log("i의 값:", i);
  }
}

콘솔 출력:

i의 값: 0
i의 값: 2
i의 값: 4
i의 값: 6
i의 값: 8

i += 2i = i + 2의 줄임말입니다. 0, 2, 4, 6, 8 — 짝수만 나옵니다. 도형 간격이나 줄무늬에 활용할 수 있습니다.

흔한 실수 3가지

실습 중 오류가 나면 아래 세 가지를 먼저 확인하세요.

실수 1: 무한 루프 — i++ 대신 i--

//  이렇게 하면 브라우저가 멈춤!
for (let i = 0; i < 10; i--) {
  console.log(i);  // 0, -1, -2, -3... 끝없이 감소
}

i가 점점 작아지니까 i < 10은 영원히 참입니다. 브라우저가 멈추면 탭을 닫고 다시 열면 됩니다.

실수 2: 중괄호 {} 빼먹기

//  중괄호를 빼먹으면 첫 줄만 반복됨
for (let i = 0; i < 10; i++)
  ellipse(i * 40, 100, 30, 30);  // 이것만 반복
  ellipse(i * 40, 200, 30, 30);  // 이건 반복 안 됨! (에러)

중괄호 {}가 없으면 바로 다음 한 줄만 반복됩니다. 두 줄 이상 반복하려면 반드시 중괄호로 감싸세요.

실수 3: i를 for문 밖에서 쓰려고 함

for (let i = 0; i < 5; i++) {
  console.log(i);  //  for문 안에서는 사용 가능
}
console.log(i);    //  에러! i is not defined

let으로 for문 안에서 만든 변수 i중괄호 안에서만 존재합니다. 밖에서는 사라집니다. 지금은 ’for문 안의 i는 밖에서 쓸 수 없다’만 기억하세요.


심화 개념 3 — 반복문으로 도형 패턴 만들기

한 줄 원 나열 — 단계별로

Step 1: 원 하나 그리기

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();
  fill(100, 150, 255);

  ellipse(20, 200, 30, 30);  // 원 하나
}

Step 2: for문으로 감싸기 (아직 잘못된 상태)

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();
  fill(100, 150, 255);

  for (let i = 0; i < 10; i++) {
    ellipse(20, 200, 30, 30);  //  10번 반복하지만 같은 위치!
  }
}

10번 그렸는데 전부 같은 자리라 원 1개로 보입니다. i를 아직 안 쓰고 있기 때문입니다.

Step 3: i를 좌표에 연결

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();
  fill(100, 150, 255);

  for (let i = 0; i < 10; i++) {
    ellipse(i * 40 + 20, 200, 30, 30);  //  i가 x좌표를 결정
  }
}

i * 40이 핵심입니다. i=0이면 x=20, i=1이면 x=60, i=2이면 x=100… 40픽셀 간격으로 원이 나열됩니다.

반복문의 핵심 질문

반복문을 쓸 때 가장 중요한 질문은 “i를 어디에 연결할 것인가?”입니다. 좌표, 크기, 색상 — 무엇이든 될 수 있습니다.

간격 조절

곱하는 숫자를 바꾸면 간격이 달라집니다.

코드 간격 결과
i * 40 + 20 40px 보통 간격 — 원끼리 딱 붙지 않음
i * 20 + 10 20px 빽빽하게 — 원(30px)보다 좁아서 겹침
i * 60 + 30 60px 넓게 — 원 사이에 빈 공간

원 크기가 30px인데 간격이 20px이면 겹치고, 60px이면 빈 공간이 생깁니다. 간격과 도형 크기의 관계를 생각해야 합니다. i < 10i < 20으로 바꾸면 원이 캔버스(400px) 밖으로 나갈 수 있습니다.

크기 변화

i크기에도 쓸 수 있습니다.

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();
  fill(100, 150, 255);

  for (let i = 0; i < 10; i++) {
    ellipse(i * 40 + 20, 200, (i + 1) * 5, (i + 1) * 5);  //  점점 커지는 원
  }
}

i=0일 때 크기 5, i=9일 때 크기 50. i + 1을 쓰는 이유는, i * 5로 하면 i=0일 때 크기가 0이라 안 보이기 때문입니다.

세로 줄

x 대신 y좌표에 i를 쓰면 세로 줄이 됩니다.

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();
  fill(100, 150, 255);

  for (let i = 0; i < 10; i++) {
    ellipse(200, i * 40 + 20, 30, 30);  //  y좌표에 i 적용
  }
}
확인 질문

x좌표와 y좌표 둘 다 i를 쓰면 어떻게 될까요?

: ellipse(i * 40 + 20, i * 40 + 20, 30, 30)대각선으로 나열됩니다.


심화 개념 4 — 반복문 + 색상 결합

i좌표에도, 색상에도 동시에 쓸 수 있습니다.

map() 함수 — 먼저 배우고 가기

i는 0~9 범위인데 색상은 0~255 범위입니다. fill(i)로 하면 0~9라서 거의 검정만 나옵니다. i의 범위를 색상 범위로 변환해야 합니다.

// map(값, 현재최소, 현재최대, 목표최소, 목표최대)

map(i, 0, 9, 0, 255);
// i=0 → 0
// i=4 → 약 113 (중간)
// i=9 → 255 (최대)

map()비례 계산을 해주는 함수입니다. ‘0~9 범위의 숫자를 0~255 범위로 바꿔줘’ — 이 한 줄이면 됩니다.

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();

  for (let i = 0; i < 10; i++) {
    let gray = map(i, 0, 9, 0, 255);
    fill(gray);
    ellipse(i * 40 + 20, 200, 30, 30);
  }
}

첫 원은 검정(0), 마지막 원은 흰색(255). 깔끔한 흑백 그라데이션입니다.

RGB 그라데이션 — 단계별로

Step 1: 전부 같은 색

for (let i = 0; i < 10; i++) {
  fill(100, 0, 0);  // 모든 원이 같은 어두운 빨강
  ellipse(i * 40 + 20, 200, 30, 30);
}

Step 2: i를 빨강 채널에 연결

for (let i = 0; i < 10; i++) {
  fill(map(i, 0, 9, 0, 255), 0, 0);  //  i가 커질수록 빨강이 진해짐
  ellipse(i * 40 + 20, 200, 30, 30);
}

i=0이면 fill(0, 0, 0) 검정, i=9이면 fill(255, 0, 0) 진한 빨강. 점점 빨개지는 원 10개입니다.

HSB 무지개

HSB의 H(색상)는 0~360 색상환입니다. for문과 결합하면 무지개가 한 줄로 만들어집니다.

function setup() {
  createCanvas(400, 400);
  colorMode(HSB, 360, 100, 100, 255);
  background(0, 0, 100);
  noStroke();

  for (let i = 0; i < 10; i++) {
    fill(map(i, 0, 9, 0, 360), 100, 100);  //  H를 0~360으로 변화 → 무지개!
    ellipse(i * 40 + 20, 200, 30, 30);
  }
}

H 값이 0에서 360까지 변하면 색상환을 한 바퀴 돕니다. 빨-주-노-초-파-보! RGB로 하려면 10개 색을 하나하나 지정해야 하는데, HSB는 map() 한 번이면 됩니다. fill()의 첫 번째 인자가 이제 H(색상환 각도)입니다.

alpha 그라데이션

function setup() {
  createCanvas(400, 400);
  background(240);
  noStroke();

  for (let i = 0; i < 10; i++) {
    fill(255, 0, 0, map(i, 0, 9, 0, 255));  //  alpha가 점점 커짐
    ellipse(i * 40 + 20, 200, 30, 30);
  }
}

첫 원은 alpha=0이라 완전 투명 — 안 보입니다. 마지막 원은 alpha=255로 진한 빨강입니다.

i를 여러 곳에 동시에 쓰기

좌표, 색상, 크기, 투명도 — i여러 곳에 동시에 쓸 수 있습니다.

function setup() {
  createCanvas(400, 400);
  colorMode(HSB, 360, 100, 100, 255);
  background(0, 0, 15);
  noStroke();

  for (let i = 0; i < 10; i++) {
    fill(map(i, 0, 9, 0, 360), 80, 100);          // 색상: 무지개
    ellipse(i * 40 + 20, 200, (i + 1) * 5, (i + 1) * 5);  // 크기: 점점 커짐
  }
}

색도 바뀌고 크기도 바뀝니다. 반복 변수 i좌표·색상·크기·투명도 어디에든 쓸 수 있다는 것이 for문의 핵심 강점입니다.

06 i to position size color

실전 사례

07 pattern examples basic grid radial

사례 1: 그라데이션 줄무늬

Step 1: 같은 색 줄무늬

function setup() {
  createCanvas(400, 400);
  noStroke();

  for (let i = 0; i < 20; i++) {
    fill(200, 100, 100);
    rect(i * 20, 0, 20, 400);  // 20px 너비 막대 20개
  }
}

전부 같은 색이라 하나의 큰 사각형처럼 보입니다.

Step 2: HSB로 색상 변화 추가

function setup() {
  createCanvas(400, 400);
  colorMode(HSB, 360, 100, 100, 255);
  noStroke();

  for (let i = 0; i < 20; i++) {
    fill(map(i, 0, 19, 0, 360), 80, 100);  //  H를 0~360으로 변화
    rect(i * 20, 0, 20, 400);
  }
}

무지개 줄무늬입니다. rect() + for + HSB + map() — 오늘 배운 것들의 조합입니다.

사례 2: 격자 패턴 (중첩 for문)

for문 안에 for문을 넣으면 2차원 격자를 만들 수 있습니다.

function setup() {
  createCanvas(400, 400);
  colorMode(HSB, 360, 100, 100, 255);
  background(0, 0, 100);
  noStroke();

  for (let y = 0; y < 10; y++) {         // 바깥: 줄 반복 (세로)
    for (let x = 0; x < 10; x++) {       // 안쪽: 각 줄 안에서 칸 반복 (가로)
      fill((x + y) * 18, 80, 100);      //  x+y로 대각선 그라데이션
      rect(x * 40, y * 40, 35, 35);
    }
  }
}

바깥 for문이 y=0일 때 안쪽 for문이 x=0~9를 전부 실행해 첫 번째 줄을 완성하고, 바깥이 y=1로 넘어가면 안쪽이 다시 x=0~9 → 두 번째 줄. 10줄 × 10칸 = 100개. (x + y)를 색상에 쓰면 대각선 방향으로 색이 변합니다.

사례 3: 원형 패턴 (5주차 예고)

원형으로 배치하려면 sin()cos()가 필요합니다. 5주차에서 배울 내용인데, 미리 결과만 봅니다.

function setup() {
  createCanvas(400, 400);
  colorMode(HSB, 360, 100, 100, 255);
  background(0, 0, 15);
  noStroke();

  for (let i = 0; i < 12; i++) {
    let angle = i * 30;  // 360 / 12 = 30도 간격
    let x = 200 + cos(radians(angle)) * 120;
    let y = 200 + sin(radians(angle)) * 120;
    fill(i * 30, 80, 100);
    ellipse(x, y, 40, 40);
  }
}

시계처럼 12개 원이 둥글게 배치되고 각각 다른 색입니다. 지금은 ‘이런 것도 가능하구나’ 정도만 기억하세요.


3교시 실습 안내

실습 과제: 기하학적 패턴 아트

3교시에서 반복문과 색상을 결합한 기하학적 패턴 아트를 만듭니다.

필수 요구사항

# 요구사항 관련 개념
1 for 반복문 1개 이상 사용 2교시: for문
2 RGB 또는 HSB 색상 활용 (흑백 금지) 1교시: 색상 체계
3 반복 변수 i좌표 또는 색상에 활용 2교시: 반복+색상 결합
4 도형 10개 이상 반복 생성 2교시: 반복 패턴

방금 본 코드들이 이미 이 조건을 충족합니다. 무엇을 만들지 막막하면 OpenProcessing에서 “geometric pattern”을 검색해 레퍼런스를 살펴보세요. 똑같이 따라할 필요 없이 아이디어만 참고하면 됩니다.

실습과제 1 안내

오늘 3교시에서 시작한 패턴 아트가 실습과제 1이 됩니다.

항목 내용
과제명 기하학적 패턴 아트
제출 기한 4주차 수업 전까지
제출 방식 P5.js Web Editor 링크 공유
평가 제출 완료 시 만점

완성도는 평가하지 않습니다. 직접 시도하고 제출하는 과정이 중요합니다.

시작 힌트

어디서부터 시작할지 막막하면 이 코드부터 시작하세요.

function setup() {
  createCanvas(400, 400);
  colorMode(HSB, 360, 100, 100, 255);
  background(0, 0, 100);
  noStroke();

  for (let i = 0; i < 10; i++) {
    fill(i * 36, 100, 100);
    ellipse(i * 40 + 20, 200, 30, 30);
  }
}

이 무지개 원 한 줄에서 출발해, 크기를 바꾸거나 줄을 추가하거나 사각형으로 바꾸거나 배경색을 바꾸며 자유롭게 실험해보세요.