콘텐츠로 이동

애니메이션 — 움직임까지 명세하기 (차시 3-4)

애니메이션 — 움직임까지 명세하기 (차시 3-4)

섹션 제목: “애니메이션 — 움직임까지 명세하기 (차시 3-4)”

Part 2: 트랙 A — VPython 3D 창작과 시뮬레이션


  • 정적 3D 조형물에 rate(), while True 루프를 활용해 애니메이션을 추가할 수 있다
  • rotate().pos 변경으로 회전과 이동 움직임을 구현할 수 있다
  • AI가 생성한 애니메이션에서 회전축 오류, 관통 이동, 속도 불일치 등의 실수를 식별할 수 있다
  • 동작을 자연어가 아닌 구조화된 ‘동작 명세서’(축, 각도, 속도, 반복)로 작성하여 AI의 애니메이션 품질을 개선할 수 있다

차시 1-2에서 학생들은 정적인 3D 캐릭터를 만들었습니다. 커비도 만들었고, 눈사람도 만들었죠. 그런데 가만히 서 있기만 합니다.

이번 차시에서는 그 캐릭터에 움직임을 추가합니다. 팔을 흔들고, 날개를 펄럭이고, 빙글빙글 돌아가는 거죠.

그런데 여기서 중요한 발견이 기다리고 있습니다.

정적 3D보다 애니메이션에서 AI가 훨씬 자주 실수합니다.

“팔을 흔들어줘”라고 시키면 — 회전축이 뒤집혀서 팔이 몸통을 관통하거나, 속도가 비현실적으로 빠르거나, 반복 루프가 엉킵니다. 왜냐하면 “흔들어줘”라는 말에는 축, 각도, 속도, 반복 조건 등 AI가 추측해야 할 정보가 너무 많기 때문입니다.

학생은 이 차시에서 “모호한 요청”과 “구조화된 동작 명세”의 차이를 몸으로 느끼게 됩니다. 그리고 규칙 파일에 애니메이션 관련 규칙을 추가하면서, “명세가 정밀할수록 결과가 좋다”는 원칙을 다시 한 번 확인합니다.


개념 1: while True + rate() — 애니메이션의 심장

섹션 제목: “개념 1: while True + rate() — 애니메이션의 심장”

비유: 애니메이션은 “초고속 그림 넘기기”입니다. 만화 한 장 한 장을 빠르게 넘기면 움직이는 것처럼 보이죠? VPython에서도 마찬가지입니다. 매 순간 도형의 위치나 각도를 아주 조금씩 바꿔주면, 그것이 움직임이 됩니다.

정확한 정의:

  • while True: — “영원히 반복해라”는 뜻. 이 안에 있는 코드가 계속 실행됩니다.
  • rate(60) — “1초에 60번만 실행해라”는 뜻. 이것이 없으면 컴퓨터가 미친 속도로 돌아서 화면이 멈춘 것처럼 보입니다.

예시로 확인:

GlowScript 3.2 VPython
mybox = box(pos=vector(0, 0, 0), color=color.red)
while True:
rate(60)
mybox.pos.x = mybox.pos.x + 0.01

이 코드를 실행하면 빨간 상자가 오른쪽으로 천천히 이동합니다. rate(60) 덕분에 1초에 60번, 매번 x좌표가 0.01씩 증가하니까, 1초에 0.6만큼 오른쪽으로 가는 거예요.

비유: 문을 열 때를 생각해보세요. 문은 경첩(힌지) 을 중심으로 회전합니다. VPython의 rotate()도 똑같습니다. “어떤 축을 중심으로, 얼마나 회전할지”를 알려줘야 합니다.

정확한 정의:

물체.rotate(angle=라디안값, axis=회전축, origin=회전중심)
  • angle: 한 번에 얼마나 회전할지 (라디안 단위. 0.01이면 아주 조금)
  • axis: 어떤 축을 중심으로 회전할지 (vector(0,1,0) = y축)
  • origin: 어디를 중심으로 회전할지 (생략하면 물체 자기 자신의 중심)

예시로 확인:

GlowScript 3.2 VPython
windmill_blade = box(pos=vector(0, 2, 0), size=vector(4, 0.3, 0.1),
color=color.yellow)
while True:
rate(60)
windmill_blade.rotate(angle=0.02, axis=vector(0, 0, 1),
origin=vector(0, 2, 0))

이 코드를 실행하면 노란 막대가 z축(화면 앞뒤 방향)을 중심으로 빙글빙글 돕니다. originvector(0, 2, 0)으로 잡았으므로 그 지점을 중심으로 회전합니다.

개념 3: .pos 변경 — 이동과 왕복

섹션 제목: “개념 3: .pos 변경 — 이동과 왕복”

비유: 놀이공원의 바이킹을 생각해보세요. 앞으로 갔다가 뒤로 옵니다. 이것을 코드로 만들려면 “방향을 바꾸는 조건”이 필요합니다. 어디까지 갔으면 돌아와라, 이런 식이죠.

정확한 정의:

물체.pos.y = 물체.pos.y + 속도

이동 방향을 바꾸려면 속도의 부호를 반전합니다.

예시로 확인 — 위아래 바운스:

GlowScript 3.2 VPython
ball = sphere(pos=vector(0, 0, 0), radius=0.5, color=color.cyan)
speed = 0.02
while True:
rate(60)
ball.pos.y = ball.pos.y + speed
if ball.pos.y > 2 or ball.pos.y < -2:
speed = -speed

공이 y좌표 2와 -2 사이를 오락가락합니다. speed의 부호가 뒤집히면서 방향이 바뀌는 거예요.

개념 4: 동작 명세서 — AI에게 움직임을 정확히 시키는 방법

섹션 제목: “개념 4: 동작 명세서 — AI에게 움직임을 정확히 시키는 방법”

비유: 안무가가 댄서에게 동작을 알려줄 때 “그냥 춤춰”라고 하지 않죠. “오른팔을 어깨 높이까지 2초에 걸쳐 올린 뒤, 1초 멈추고, 2초에 걸쳐 내려”라고 합니다. AI에게도 마찬가지입니다.

정확한 정의: 동작 명세서란 움직임을 다음 요소로 분해하여 작성하는 문서입니다.

  • 대상 — 어떤 도형이 움직이는가
  • 축(axis) — 어떤 방향으로 움직이는가 (x/y/z)
  • 범위 — 어디서 어디까지 움직이는가 (각도 또는 좌표)
  • 속도 — 얼마나 빠르게 움직이는가
  • 반복 조건 — 왕복인가, 한 방향인가, 몇 번 반복인가

모호한 요청 vs 구조화된 동작 명세:

구분예시
모호한 요청”팔을 흔들어줘”
구조화된 명세”왼팔(left_arm)을 y축 기준으로 -30도~+30도 범위에서 왕복 회전. 회전 중심은 어깨 위치 vector(-1.5, 1, 0). 한 사이클(왕복) 1초. 무한 반복.”

이 실습은 차시 1-2에서 만든 캐릭터를 기반으로 합니다. 아래 예제는 “회전하는 풍차”를 사용하지만, 학생은 4종 중 하나를 자유롭게 선택합니다.

캐릭터/예제 선택지 (4종):

  • 걷는 로봇 — 양 팔/다리가 번갈아 움직이는 보행 애니메이션
  • 날갯짓하는 새 — 날개가 위아래로 펄럭이며 전진
  • 회전하는 풍차 — 날개가 일정 속도로 회전
  • 뛰어노는 강아지 — 상하 바운스 + 꼬리 흔들기

Step 1: 차시 1-2 복습 — 내 캐릭터의 규칙 파일 확인 (5분)

섹션 제목: “Step 1: 차시 1-2 복습 — 내 캐릭터의 규칙 파일 확인 (5분)”

선생님 스크립트:

“지난 시간에 만든 캐릭터 코드를 GlowScript에서 열어주세요. 그리고 규칙 파일도 열어보세요. 지난 시간에 추가한 규칙이 몇 개였죠? 오늘은 거기에 더 추가할 거예요. 왜냐면 오늘은 움직임을 다루거든요. 정적인 3D보다 AI가 훨씬 더 자주 틀립니다.”


Step 2: 직접 코딩 — 내 캐릭터에 애니메이션 추가 (20분)

섹션 제목: “Step 2: 직접 코딩 — 내 캐릭터에 애니메이션 추가 (20분)”

선생님 스크립트:

“자, 먼저 직접 코딩으로 움직임을 추가해볼 거예요. 왜 직접 먼저 해볼까요? AI에게 시켰을 때 뭐가 이상한지 알려면, 내가 먼저 해봐야 기준이 생기니까요.

치트시트를 볼게요. 새로운 세 가지를 알려줄게요.”

**1. 기본 구조 (무한 반복)**
```python
while True:
rate(60) # 1초에 60번 실행
# (여기에 움직임 코드)
```
**2. 회전**
```python
물체.rotate(angle=0.01, axis=vector(0,1,0),
origin=vector(x,y,z))
```
| axis 값 | 회전축 | 동작 |
|---------|--------|------|
| `vector(1,0,0)` | x축 | 끄덕끄덕 |
| `vector(0,1,0)` | y축 | 고개 좌우 |
| `vector(0,0,1)` | z축 | 갸우뚱 |
**3. 이동**
```python
물체.pos.x = 물체.pos.x + 0.01 # 오른쪽으로
물체.pos.y = 물체.pos.y + 0.01 # 위로
```
**4. 왕복 (방향 바꾸기)**
```python
if 물체.pos.y > 2 or 물체.pos.y < -2:
speed = -speed
```
**5. 삼각함수 왕복 (부드러운 흔들림)**
```python
t = t + 0.02
물체.pos.y = sin(t) * 범위
```

“풍차를 예로 들어볼게요. 풍차 날개 코드를 먼저 만들고, 그 아래에 while True를 추가합니다.”

풍차 기본 코드 (학생이 따라 칠 코드):

GlowScript 3.2 VPython
# 풍차 기둥
pole = cylinder(pos=vector(0, -2, 0), axis=vector(0, 4, 0),
radius=0.15, color=vector(0.6, 0.4, 0.2))
# 풍차 날개 4개
blade1 = box(pos=vector(0, 2, 0.1), size=vector(3, 0.3, 0.05),
color=color.white)
blade2 = box(pos=vector(0, 2, 0.1), size=vector(0.3, 3, 0.05),
color=color.white)
# 중심 허브
hub = sphere(pos=vector(0, 2, 0.15), radius=0.2,
color=color.red)
# 애니메이션!
while True:
rate(60)
blade1.rotate(angle=0.03, axis=vector(0, 0, 1),
origin=vector(0, 2, 0))
blade2.rotate(angle=0.03, axis=vector(0, 0, 1),
origin=vector(0, 2, 0))

“실행해보세요. 날개가 돌아가죠?

이제 숫자를 바꿔보세요. angle=0.030.1로 바꾸면? 더 빨라지죠. axisvector(1,0,0)으로 바꾸면? 회전 방향이 완전히 달라집니다. 이렇게 숫자를 바꿔보면서 감을 잡는 게 가장 빠른 방법이에요.”

예상 반응과 교사 대응:

  • “돌아가요!” → 좋습니다! “angle 값을 바꿔보세요. 어떻게 달라지나요?”
  • “한쪽만 돌아요” → “blade1과 blade2 둘 다 rotate를 넣었는지 확인하세요.”
  • “이상한 방향으로 돌아요” → “axis를 바꿔보세요. vector(0,0,1)이 z축이에요.”
  • “너무 빠르게/느리게 돌아요” → “angle 값이 한 프레임의 회전량이에요. 작게 하면 느려지고, 크게 하면 빨라져요.”
  • “origin이 뭐예요?” → “회전 중심이에요. 문의 경첩 같은 거예요. 안 쓰면 물체 자기 중심으로 돌아요.”

Step 3: AI에게 같은 애니메이션 요청 — 모호한 버전 (15분)

섹션 제목: “Step 3: AI에게 같은 애니메이션 요청 — 모호한 버전 (15분)”

선생님 스크립트:

“자, 이제 AI에게 시켜볼 거예요. 그런데 차시 1-2에서 했던 것처럼, 일부러 대충 시켜볼 거예요.

지난 시간에는 ‘커비 만들어줘’라고 대충 시켰더니 발이 머리 위에 올라갔잖아요. 오늘은 움직임을 대충 시켜볼 겁니다. 어떤 일이 벌어질까요?”

학생에게 이렇게 시키라고 안내합니다:

지난 시간에 만든 VPython 풍차(또는 로봇/새/강아지)에 애니메이션을 추가해줘.
자연스럽게 움직이게 해줘.

“AI가 준 코드를 GlowScript에 붙여넣고 실행해보세요. 그리고 아까 내가 직접 만든 것과 비교하세요.”

AI의 전형적 실패 패턴 (선생님이 알아둘 것):

flowchart LR
A["모호한 요청<br/>'자연스럽게 움직여줘'"] --> B["회전축 오류<br/>팔이 몸통을 관통"]
A --> C["속도 불일치<br/>비현실적으로 빠름/느림"]
A --> D["origin 누락<br/>물체 중심으로 회전"]
A --> E["rate() 누락<br/>화면이 멈춘 것처럼 보임"]
A --> F["불필요한 동작 추가<br/>요청 안 한 움직임"]

“뭐가 이상한지 종이에 적어보세요. 이렇게요:”

AI 애니메이션 비교 메모:

  • 회전 방향이 __________________
  • 속도가 __________________
  • 회전 중심이 __________________
  • 다른 문제: __________________

예상 반응:

  • “팔이 몸통 속으로 들어가요!” → 회전축 오류 (가장 흔함)
  • “너무 빠르게 돌아요!” → rate()나 angle 값 문제
  • “이상한 방향으로 회전해요!” → axis 벡터가 의도와 다름
  • “내가 원한 게 아닌데 막 움직여요!” → 불필요한 동작 추가

“방금 여러분이 발견한 것들 — 이것이 애니메이션에서 AI가 자주 하는 실수예요. 정적 3D에서는 ‘좌표가 틀리다’ 수준이었는데, 움직임에서는 더 복잡한 실수가 나오죠. 축, 중심, 속도, 범위 — 알려주지 않으면 AI가 전부 추측하거든요.”


Step 4: 실패 기록 → 규칙 파일에 추가 (10분)

섹션 제목: “Step 4: 실패 기록 → 규칙 파일에 추가 (10분)”

선생님 스크립트:

“방금 발견한 AI 실수를 규칙으로 바꿔봅시다. 차시 1-2에서 했던 것처럼, 규칙 만드는 공식을 쓰세요.”

규칙 변환 예시:

발견: AI가 팔의 회전 중심을 팔 가운데로 잡아서, 팔이 몸통을 관통함

규칙: rotate()의 origin을 반드시 명세에 포함할 것. 회전 중심은 관절 위치(어깨, 엉덩이 등)로 지정해야 한다. ← 사건: “팔을 흔들어줘”라고 했더니 팔이 자기 중심으로 돌아서 몸통을 관통

발견: AI가 rate() 없이 while True를 써서 화면이 멈춤

규칙: while True 안에 반드시 rate()을 포함할 것 ← 사건: 애니메이션 코드를 실행했더니 화면이 먹통이 됨

“규칙 파일을 열어서, ‘3D 창작/시뮬레이션에서의 규칙’ 아래에 추가하세요. 최소 2개 이상 추가해봅시다.”


Step 5: 동작 명세서 작성 + AI 재요청 (30분)

섹션 제목: “Step 5: 동작 명세서 작성 + AI 재요청 (30분)”

이 단계가 이 차시의 핵심입니다. “대충 시키면 대충 나온다”를 체험한 학생이, 이번에는 정확하게 시켜봅니다.

선생님 스크립트:

“‘팔을 흔들어줘’가 왜 안 됐을까요? AI가 판단해야 할 것이 너무 많았기 때문이에요.

  • 어떤 축으로? → AI가 추측
  • 얼마나? → AI가 추측
  • 얼마나 빠르게? → AI가 추측
  • 어디를 중심으로? → AI가 추측

추측이 4개면, 다 맞을 확률은… 거의 0이에요. 그래서 동작 명세서를 써야 합니다.”

**캐릭터:** \_\_\_\_\_\_\_\_\_\_\_\_ / **작성자:** \_\_\_\_\_\_\_\_\_\_\_\_
**동작 #1**
| 항목 | 내용 |
|------|------|
| 대상 | \_\_\_\_\_\_\_\_\_\_\_\_ (어떤 도형) |
| 종류 | [ ] 회전 [ ] 이동 [ ] 크기 변화 |
| 축(axis) | `vector( _, _, _ )` |
| 범위 | \_\_\_\_도 ~ \_\_\_\_도 (또는 좌표 \_\_\_ ~ \_\_\_) |
| 속도 | 한 사이클 약 \_\_\_초 |
| 회전 중심(origin) | `vector( _, _, _ )` |
| 반복 | [ ] 무한 왕복 [ ] 한 방향 [ ] \_\_\_회 반복 |
**동작 #2** -- 위와 동일 양식으로 작성
**주의사항 체크리스트:**
- [ ] 도형끼리 관통하지 않을 것
- [ ] rate(60)을 반드시 포함할 것
- [ ] 명시하지 않은 동작을 추가하지 말 것

“자, 여러분이 선택한 캐릭터의 동작 명세서를 직접 써보세요. 예를 들어 풍차라면 이렇게요.”

풍차 동작 명세서 예시:

캐릭터: 풍차 / 작성자: 김선생

동작 #1: 날개 회전

항목내용
대상blade1, blade2
종류회전
vector(0, 0, 1) — z축 (화면 앞뒤)
범위무한 회전 (각도 제한 없음)
속도1바퀴에 약 5초 (angle=0.02, rate=60 기준)
회전 중심vector(0, 2, 0) — 기둥 꼭대기
반복무한

주의사항:

  • blade1과 blade2가 동일한 속도, 축, 중심으로 회전할 것
  • rate(60)을 반드시 포함
  • 기둥(pole)과 허브(hub)는 움직이지 않을 것

“동작 명세서를 다 썼으면, 이걸 AI에게 보내보세요. 앞에 차시 1-2에서 만든 캐릭터의 정적 명세도 함께 보내야 해요. 그래야 AI가 ‘어떤 캐릭터의 어떤 부분을 어떻게 움직일지’를 정확히 알 수 있어요.”

정밀 명세 프롬프트 예시 (학생이 참고할 수 있도록 화면에 띄움):

GlowScript VPython으로 다음 풍차를 만들고 애니메이션을 추가해줘.
[정적 구조]
1. 기둥: cylinder, pos=(0,-2,0), axis=(0,4,0), radius=0.15, 갈색
2. 날개1: box, pos=(0,2,0.1), size=(3,0.3,0.05), 흰색
3. 날개2: box, pos=(0,2,0.1), size=(0.3,3,0.05), 흰색
4. 허브: sphere, pos=(0,2,0.15), radius=0.2, 빨간색
[동작]
- blade1, blade2를 z축(vector(0,0,1)) 기준으로 회전
- 회전 중심: vector(0,2,0)
- angle=0.02, rate(60) 사용
- 기둥과 허브는 움직이지 않음
[주의사항]
- while True + rate(60) 반드시 포함
- 위에 명시하지 않은 동작 추가 금지

“결과가 아까 모호하게 시켰을 때랑 어떻게 다른가요?”

예상 반응:

  • “이번에는 제대로 돌아요!” → “명세를 정확히 쓰니까 결과가 좋아졌죠?”
  • “거의 맞는데 속도가 좀 달라요” → “rate()과 angle 값을 명세에 더 정확히 적으면 개선될 거예요.”
  • “그래도 좀 이상한데요” → “어디가 이상한지 수용 기준으로 판정해봅시다.”

Step 6: 종합 프로젝트 — 캐릭터에 애니메이션 완성 (15분)

섹션 제목: “Step 6: 종합 프로젝트 — 캐릭터에 애니메이션 완성 (15분)”

“마지막으로, 여러분이 선택한 캐릭터로 종합 프로젝트를 완성해봅시다. 동작 명세서를 먼저 쓰고, AI에게 보내고, 결과를 확인하세요.”

캐릭터별 동작 명세 가이드:

걷는 로봇:

  • 왼팔/오른팔: x축 기준 -20도~+20도 왕복, origin=어깨 위치
  • 왼다리/오른다리: x축 기준 -20도~+20도 왕복, 팔과 반대 위상
  • 팔과 다리의 반복 주기 동일 (약 1초)

날갯짓하는 새:

  • 왼날개/오른날개: z축 기준 -30도~+30도 왕복, origin=몸통 연결부
  • 몸 전체: x축으로 천천히 전진 (pos.x += 0.01)
  • 날갯짓 주기 약 0.5초

회전하는 풍차:

  • 날개 전체: z축 기준 무한 회전, origin=기둥 꼭대기
  • 기둥과 허브는 고정

뛰어노는 강아지:

  • 몸 전체: y축 위아래 바운스 (y=-0.5~+0.5 왕복)
  • 꼬리: y축 기준 -20도~+20도 왕복, origin=엉덩이 위치
  • 바운스 주기와 꼬리 주기를 다르게 설정

“5분 뒤에 결과를 함께 보겠습니다. 완성 못 해도 괜찮아요 — 동작 명세서를 잘 썼느냐가 더 중요합니다.”


회전하는 풍차 (완성 예제):

GlowScript 3.2 VPython
# === 정적 구조 ===
# 기둥
pole = cylinder(pos=vector(0, -2, 0), axis=vector(0, 4, 0),
radius=0.15, color=vector(0.6, 0.4, 0.2))
# 날개 (십자 모양)
blade1 = box(pos=vector(0, 2, 0.1), size=vector(3, 0.3, 0.05),
color=color.white)
blade2 = box(pos=vector(0, 2, 0.1), size=vector(0.3, 3, 0.05),
color=color.white)
# 중심 허브
hub = sphere(pos=vector(0, 2, 0.15), radius=0.2, color=color.red)
# === 애니메이션 ===
while True:
rate(60)
# z축 기준 회전, 중심은 기둥 꼭대기
blade1.rotate(angle=0.02, axis=vector(0, 0, 1),
origin=vector(0, 2, 0))
blade2.rotate(angle=0.02, axis=vector(0, 0, 1),
origin=vector(0, 2, 0))

꼬리 흔드는 강아지 (부분 예제 — 바운스 + 꼬리):

GlowScript 3.2 VPython
# 몸통
body = ellipsoid(pos=vector(0, 0, 0), size=vector(2, 1, 1),
color=vector(0.8, 0.5, 0.2))
# 머리
head = sphere(pos=vector(1.2, 0.5, 0), radius=0.45,
color=vector(0.8, 0.5, 0.2))
# 꼬리
tail = cylinder(pos=vector(-1, 0.3, 0), axis=vector(-0.6, 0.4, 0),
radius=0.06, color=vector(0.8, 0.5, 0.2))
# 애니메이션 변수
bounce_speed = 0.02
t = 0
while True:
rate(60)
t = t + 0.05
# 바운스 (몸 전체)
dy = sin(t * 3) * 0.3
body.pos.y = dy
head.pos.y = 0.5 + dy
tail.pos.y = 0.3 + dy
# 꼬리 흔들기 (y축 기준 좌우)
tail.rotate(angle=0.05 * cos(t * 8), axis=vector(0, 1, 0),
origin=vector(-1, 0.3 + dy, 0))

자주 하는 실수 (AI가 하는 실수 포함)

섹션 제목: “자주 하는 실수 (AI가 하는 실수 포함)”
**규칙:** "while True 안에 rate()이 반드시 있는지 확인한다."
**규칙:** "rotate()에 origin을 반드시 명시한다. 관절 위치를 구체적 좌표로 알려줘야 한다."
**규칙:** "회전축을 vector(x,y,z)로 명시적으로 요청한다."
**규칙:** "회전 범위(최소각~최대각)를 반드시 명세에 포함한다."
**규칙:** "동시에 움직이는 부위가 있으면 관통 여부를 눈으로 확인한다."

수용 기준 워크시트:

이것을 AI 결과를 보기 전에 작성하세요.

수용 기준 워크시트 — 애니메이션

캐릭터: ____________ / 이름: ____________

[필수] 반드시 통과해야 하는 기준

  • while True + rate()이 포함되어 있다
  • 회전축(axis)이 내 명세와 일치한다
  • 회전 중심(origin)이 관절 위치에 있다
  • 움직이는 도중 도형끼리 관통하지 않는다
  • _______________________________________________

[선호] 되면 좋지만 필수는 아닌 기준

  • 속도가 자연스럽다 (너무 빠르거나 느리지 않다)
  • 왕복 범위가 현실적이다 (360도 회전 아님)
  • _______________________________________________

[판정]

  • AI 결과가 필수 기준을 모두 통과했는가? [ ] 예 / [ ] 아니오
  • 통과 못 한 기준: ________________________________
  • 규칙 파일에 추가할 내용: __________________________

잘 쓴 수용 기준 예시 (걷는 로봇):

  • (필수) “왼팔과 오른팔이 반대 위상으로 움직인다 (한쪽이 앞이면 다른 쪽은 뒤)”
  • (필수) “팔의 rotate() origin이 어깨 좌표와 일치한다”
  • (선호) “팔과 다리의 흔들림 주기가 동일하다 (자연스러운 걸음)”

부족한 수용 기준 예시:

  • “자연스럽게 움직여야 한다” — 주관적, 검증 불가
  • “잘 걸어야 한다” — 기준이 아님

차시 1-2에서 가져온 규칙 (예시):

## 3D 창작/시뮬레이션에서의 규칙
- 좌표를 명시하지 않으면 AI가 임의로 배치한다
→ 모든 도형의 pos를 반드시 명세에 포함할 것
← 사건: 발이 머리 위에 나옴
- AI는 명세에 없는 도형을 임의로 추가한다
→ "명시하지 않은 도형은 추가하지 마"를 포함할 것
← 사건: 커비인데 팔을 추가해줌

이 차시에서 추가할 규칙 (3~5개):

## 애니메이션 규칙
- AI는 rotate()의 origin을 생략하여 물체가 자기 중심으로 회전한다
→ origin을 반드시 관절 좌표로 명시할 것
← 사건: 팔이 어깨가 아니라 팔 중앙에서 빙글빙글 돌았음
- AI는 회전축을 혼동한다 (y축과 z축을 뒤바꿈)
→ 회전축을 vector로 명시할 것 (예: axis=vector(1,0,0))
← 사건: 팔이 앞뒤로 흔들려야 하는데 좌우로 흔들렸음
- 동시 움직임(compound)의 origin 관계를 AI가 무시한다
→ 부모-자식 관계를 명세에 명시할 것
← 사건: 어깨와 팔을 따로 움직여서 팔이 어깨에서 빠졌음
- AI는 rate() 값과 dt의 관계를 맞추지 못한다
→ rate와 dt를 동시에 명시할 것 (예: rate(100), dt=0.01)
← 사건: 애니메이션이 너무 빨라서 눈으로 확인 불가
- 반복 움직임의 범위를 명시하지 않으면 AI가 360도 회전시킨다
→ 흔들림 범위를 각도로 명시할 것 (예: -30°~+30°)
← 사건: 팔이 흔들리는 게 아니라 프로펠러처럼 360도 회전

GlowScript 3.2 VPython
# 걷는 로봇 — 팔과 다리가 번갈아 흔들림
scene.width = 600
scene.height = 600
scene.background = vector(0.06, 0.09, 0.16)
# 몸통
body = box(pos=vector(0, 0, 0), size=vector(0.6, 1, 0.4), color=vector(0.3, 0.5, 0.8))
# 머리
head = sphere(pos=vector(0, 0.8, 0), radius=0.3, color=vector(0.9, 0.75, 0.6))
# 왼팔 (어깨에서 아래로)
left_arm = box(pos=vector(-0.45, -0.2, 0), size=vector(0.15, 0.6, 0.15), color=vector(0.3, 0.5, 0.8))
# 오른팔
right_arm = box(pos=vector(0.45, -0.2, 0), size=vector(0.15, 0.6, 0.15), color=vector(0.3, 0.5, 0.8))
# 왼다리
left_leg = box(pos=vector(-0.15, -0.8, 0), size=vector(0.2, 0.6, 0.2), color=vector(0.2, 0.2, 0.6))
# 오른다리
right_leg = box(pos=vector(0.15, -0.8, 0), size=vector(0.2, 0.6, 0.2), color=vector(0.2, 0.2, 0.6))
# 애니메이션 변수
t = 0
dt = 0.01
swing_speed = 3
swing_range = 0.5 # 라디안 (약 30도)
while True:
rate(100)
angle = swing_range * sin(swing_speed * t)
# 팔: 어깨(y=0.1) 기준으로 회전, 반대 위상
left_arm.pos = vector(-0.45, 0.1 - 0.3*cos(angle), 0.3*sin(angle))
right_arm.pos = vector(0.45, 0.1 - 0.3*cos(-angle), 0.3*sin(-angle))
# 다리: 엉덩이(y=-0.5) 기준으로 회전, 팔과 반대
left_leg.pos = vector(-0.15, -0.5 - 0.3*cos(-angle), 0.3*sin(-angle))
right_leg.pos = vector(0.15, -0.5 - 0.3*cos(angle), 0.3*sin(angle))
t = t + dt
목표수준 0 (미달)수준 2 (기대)수준 3 (우수)
회전축 오류 식별AI 결과를 그대로 수용회전축/origin 오류를 1개 이상 발견오류 발견 + 구체적 수정 요청 작성
동작 명세 작성”팔을 흔들어줘” 수준축/각도/속도를 포함한 동작 명세동기화 조건, 반복 범위까지 명세
수용 기준사후 감각적 판단회전축/origin 포함 기준 2개 이상수치(각도, 주기) 기반 기준 포함
규칙 구축미추가애니메이션 규칙 2개 이상규칙이 재사용 가능한 형태

차시 5-6: “물리 시뮬레이션 — 이제 수치로 검증한다” 검증 방법이 “눈”에서 “수식”으로 올라갑니다. 포물선, 단진자, 충돌 시뮬레이션에서 AI가 만든 결과를 물리 공식으로 검증합니다. “보기에 괜찮다 ≠ 정확하다”를 수치로 증명하는 시간입니다.