0biglife.

천 시뮬레이션

canvas

  • Canvas
  • 물리 시뮬레이션
  • Verlet
  • 인터랙션
  • ZIP 다운로드

코드

1<!DOCTYPE html>
2<html lang="ko">
3  <head>
4    <meta charset="UTF-8" />
5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6    <title>천 시뮬레이션</title>
7    <link rel="stylesheet" href="./style.css" />
8  </head>
9  <body>
10    <canvas id="cloth">천 시뮬레이션 데모</canvas>
11    <p id="fallback"></p>
12    <div id="hint">드래그로 잡아당기기 · 세게 당기면 찢어짐 · 더블클릭 리셋</div>
13    <script src="./script.js"></script>
14  </body>
15</html>
16

아이디어

천은 점(질량)과 그 사이를 잇는 제약(constraint)의 격자다. 각 점은 베를레 적분으로 움직이고, 제약은 매 프레임 길이를 원래대로 되돌리려 한다. 한계 이상으로 늘어난 제약은 끊어진다 — 그것이 '찢김'이다.

핵심 코드

베를레 적분은 속도를 저장하지 않는다. 현재 위치와 이전 위치의 차이가 곧 속도다.

1const vx = (p.x - p.px) * friction;
2const vy = (p.y - p.py) * friction;
3p.px = p.x;
4p.py = p.y;
5p.x += vx;
6p.y += vy + gravity * dt * dt;

제약 이완은 두 점을 원래 길이로 끌어당기고, 너무 늘어났으면 끊는다.

1const d = Math.hypot(dx, dy);
2if (d > rest * TEAR) removeConstraint();
3else applyCorrection((rest - d) / d);

인터랙션

드래그로 천의 한 점을 잡아 끈다. 세게 당기면 제약이 한계를 넘어 찢어진다. 바람이 천을 흔든다. 더블클릭으로 리셋.

Index

아이디어핵심 코드인터랙션