입자계 물리

1. 입자계 시스템

유명한 물리학자 리처드 파인만은 모든 지식이 파괴된 인류에게 단 한 문장만 전할 수 있다면 무엇을 전하겠냐는 질문에 이렇게 답했다고 합니다.

모든 물질은 원자로 이루어져 있다.

이 말은 원자의 관점에서 세상을 보지 않으면 제대로 물질 세계를 이해할 수 없다는 뜻이기도 합니다. 과학의 시작은 원자론에서부터 시작되었다고 해도 과언이 아닙니다. 모든 물질은 원자로 이루어져 있고 모든 물체의 운동도 각 입자의 운동의 합으로 설명할 수 있습니다.

그러나 우리가 물리학 시간에 물체의 운동도 분석할 때 쉽게 접근하기 위해 물체를 하나의 입자로 가정하고 설명해 왔습니다. 그러나 모든 물체는 부피를 가지고 수많은 원자로 구성되어 있어 실제 자연현상을 컴퓨터로 시뮬레이션 하기 위해서는 여러 입자의 운동을 입자계 시스템으로 표현할 필요가 있습니다.

특히 불, 물, 연기와 같은 유체의 운동을 표현하기 위해서는 한 두개의 입자가 아닌 입자계 시스템을 사용합니다.

"파티클 효과"

우리는 앞선 차시에서 클래스와 객체, 배열, 반복문에 대해서 배웠습니다. 입자계 시스템을 만들 때도 바로 클래스, 객체, 배열, 반복문을 사용합니다. 그럼 활동 1을 통해 분수를 만들어볼까요?

분수를 만들기 위해서 다음과 같이 Particle 클래스와 실행 부분을 구상해 봅시다. 이렇게 직접 코딩하기 전에 우리에게 친숙한 말로 기능을 먼저 구현하는 것을 의사 코드(pseudo code)라고 합니다.

class Particle{
  constructor(x, y) {
    this.위치 = 초기 위치;
    this.속도 = 랜덤한 방향과 속도(속도 크기는 0.5~2)
    this.객체생존시간 = 객체가 유지되는 정도;
  }
  applyForce() { 중력 작용 }
  finished() { 객체 생존시간이 지나면 true를 반환 }
  edges() { 객체가 바닥에 튕기게 설정 }
  update() { 객체의 가속도, 속도, 위치 갱신 }
  show() { 객체 그리기 }
}

function setup() { 캔버스 크기 설정 }

function draw() {
  Particle 클래스로 객체를 생성하여 particles 배열에 저장
  객체에 중력을 적용하고 바닥을 설정하고, 위치를 갱신하고, 캔버스에 그림
  객체 생존시간이 지난 객체는 particles 배열에서 제거
}  

이렇게 전체적인 프로그래밍 구상이 끝나면 해당하는 기능을 구현하기 위해 레퍼런스를 찾아가면서 해당 명령어를 찾아 적용시키기만 하면 됩니다. 활동 1을 구현하기 위해서 새롭게 나온 함수는 다음과 같습니다.

// 임의의 각도에서 새로운 2D 단위 벡터를 생성합니다.
p5.Vector.random2D();
// x=50, y=20 인자를 Particle 클래스에 넘기면서 
// 새로운 객체를 형성하여 배열에 순서대로 저장함.
배열.push(new Particle(50,20));
// 객체를 배열에서 제거
// splice(항목 위치, 삭제할 항목 수)
배열.splice(i, 1);

활동 1. 분수 만들기

코드를 실행해 보면 객체가 한 점에서 랜덤한 속도로 생성되어 분수에서 물이 나오는 것처럼 보여지는 것을 확인할 수 있습니다. 활동 1 코드에서 생성되는 객체의 갯수나 생존시간을 조절해보면서 제일 그럴듯한 분수의 모양을 만들어 보세요.

활동 1코드를 약간 수정하면 불꽃이 타오르는 효과도 낼 수 있답니다. 어디를 수정해야 할까요? 일단 불꽃은 위로 타오르니까 중력의 영향을 없앨 필요가 있고, 대신 윗방향으로 등속운동하고 가정해 봅시다. 그럼 활동 2의 코드를 보시면서 어디를 수정했는지 살펴보시기 바랍니다. 그리고 여러분 만의 불꽃을 만들어보세요.

활동 2. 불꽃 효과 만들기

2. 입자계로 불꽃놀이 만들기

하늘에서 터지는 불꽃놀이도 입자계 시스템으로 표현할 수 있습니다. 앞서 분수와의 차이점은 분수는 한점에서 계속 객체를 생성하는 것이라면 불꽃놀이는 각 위치별로 수백개의 객체를 배열로 저장해서 한 번에 보여주는 것입니다.

아래 의사 코드처럼 각 위치별로 fireworks 객체를 생성하고 그 안에서 particles객체를 생성합니다. 이중으로 클래스를 사용하는 것입니다.

// 불꽃놀이 본체 클래스
class Firework{
  constructor(x, y) {
    this.위치 = 랜덤한 위치;
    Particle 클래스로 100 이상의 객체를 생성하여 particles 배열에 저장
  }  
}
// 불꽃놀이 입자 클래스
class Particle{
  constructor(x, y) {
    this.위치 = 초기 위치;
    this.속도 = 랜덤한 방향과 속도
    this.객체생존시간 = 객체가 유지되는 정도;
  }
  applyForce() { 중력 작용 }
  done() { 객체 생존시간이 지나면 true를 반환 }
  update() { 객체의 가속도, 속도, 위치 갱신 }
  show() { 객체 그리기 }
}

function setup() { 캔버스 크기 설정 }

function draw() {
  Firework 클래스로 fireworks 객체 생성 (일정한 확률로 생성하게 )
  particles 객체가 모두 사라지면 fireworks 객체도 제거
}  

그럼 활동 3을 통해 직접 코딩으로 구현해 보겠습니다. 활동 1보다 약간 구조가 복잡해졌지만 천천히 따라가면서 실행해보면 이해가 될 것입니다. 코드에서 불꽃놀이 입자의 갯수라던지, 발생 확률, 불꽃놀이 입자의 속도의 범위를 한번 바꿔서 실행해 보세요.

활동 3. 불꽃놀이 만들기

활동 3의 코드를 수정하여 좀 더 불꽃놀이와 유사하게 만들어 봅시다. 참고 예제

업데이트: