If you're seeing this message, it means we're having trouble loading external resources on our website.

웹 필터가 올바르게 작동하지 않으면 도메인 *. kastatic.org*.kasandbox.org이 차단되어 있는지 확인하세요.

주요 내용

움직임 가리키기

초기에 나온 예제 하나를 다시 살펴봅시다. Mover 객체가 마우스 쪽으로 가속하는 예제입니다.
지금까지 그렸던 거의 모든 모양은 원형입니다. 원형 모양을 그리면 여러 이유로 편리합니다. 그중 하나는 회전 문제를 고려할 필요가 없다는 것입니다. 원은 회전시켜도 모양이 똑같습니다. 그러나 언젠가는 물체가 움직이는 방향을 가리키는 상황을 만들어야 할 때가 있습니다. 개미나 고양이나 우주선을 같은 물체를 그릴 때 필요하겠군요. 그리고 "이동 방향을 가리키는 것"은 “속도 벡터에 따라 회전하는 것”과 같습니다. 속도는 x와 y 성분을 갖는 벡터입니다. 그러나 ProcessingJS에서 회전하기 위해서는 각이 필요합니다. 여기에 객체의 속도 벡터를 나타낸 그림을 한 번 더 그려봅시다.
그렇습니다. 탄젠트의 정의가 다음과 같다는 것을 알고 있습니다.
()=yx
문제는 위에서 속도를 알고 있지만, 각은 모른다는 것입니다. 따라서 식을 각에 대해 풀어야 합니다. 여기서 탄젠트의 역함수로 알려져 있는 특별한 함수를 사용해야합니다. 이 함수는 아크탄젠트(arctangent) 또는, tan-1이라고 합니다. (또한 사인의 역함수와 코사인의 역함수가 있습니다.)
어떤 값 a의 탄젠트가 b라는 값이라면 b에 대한 탄젠트의 역함수는 a입니다. 예를 들어
tangent(a)=b라면
a=arctangent(b)이다
역함수 관계를 잘 알겠나요? 이제 위 사실을 이용하여 식을 각에 대해 풀어 봅시다.
tangent(angle)=velocityy/velocityx라면
angle=arctangent(velocityy/velocityx)이다
이제 공식을 알아냈으니, 공식이 mover의 display() 함수 어느 부분에 들어가야 할지 생각해봅시다. ProcessingJS에서 아크탄젠트 함수는 atan()으로 표시합니다. 자바스크립트도 기본적으로 Math.atan()(뿐만 아니라 다른 삼각함수도 포함)을 내재하고 있습니다. 그러나 ProcessingJS에서 제공하는 함수를 이용해 보겠습니다.
Mover.prototype.display = function () {
  var angle = atan(this.velocity.y / this.velocity.x);

  stroke(0, 0, 0);
  fill(127, 127, 127);
  pushMatrix();
  rectMode(CENTER);
  translate(this.position.x, this.position.y);
  rotate(angle);
  rect(0, 0, 30, 10);
  popMatrix();
};
위 코드는 조금만 다듬으면 완성할 수 있고, 지금도 거의 동작합니다. 그런데 큰 문제가 있습니다. 아래 그림과 같이 두 개의 속도 벡터를 살펴봅시다.
비록 겉으로는 비슷하지만 두 벡터는 서로 반대 방향을 가리킵니다! 그러나 각각의 벡터에 각에 대해 정리한 공식을 적용하면…
V1 ⇒ angle = atan(3/-4) = atan(-0.75) = -0.644라디안 = -57도
V2 ⇒ angle = atan(-3/4) = atan(-0.75) = -0.644라디안 = -57도
…벡터가 모두 똑같은 각을 가지고 있습니다. 두 각이 같을 수는 없습니다. 왜냐하면 벡터가 서로 반대 방향을 가리키기 때문입니다! 이는 컴퓨터 그래픽에서 일반적인 문제입니다. 양수/음수 문제를 해결하려고 다수의 조건문과 함께 단순히 atan()을 사용하는 것 보다는 ProcessingJS에서 (뿐만 아니라 자바스크립트와 많은 프로그래밍 언어에서도) atan2()라는 유용한 함수를 사용해 보세요.
Mover.prototype.display = function () {
  var angle = atan2(this.velocity.y, this.velocity.x);

  stroke(0, 0, 0);
  fill(127, 127, 127);
  pushMatrix();
  rectMode(CENTER);
  translate(this.position.x, this.position.y);
  rotate(angle);
  rect(0, 0, 30, 10);
  popMatrix();
};
이 코드를 좀 더 단순화하기 위해 PVector 객체가 제공하는 heading() 함수를 사용해 봅시다. 이 함수는 atan2()를 호출하여 임의의 PVector에 대해 2D 방향각을 라디안 단위로 변환하여 보여줍니다.
다음은 이 모든 것을 종합해서 만든 프로그램입니다. 마우스를 물체 위로 갖다 대서 어떻게 회전하는지 살펴보세요.

본 "내추럴 시뮬레이션" 과정은 다니엘 쉬프만(Daniel Shiffman)이 저술한 "The Nature of Code"의 내용을 차용한 것이며, 본 내용물의 저작권은 Creative Commons Attribution-NonCommercial 3.0 Unported License를 적용합니다.