우리는 왜 게임 물리학에서 피타고라스 정리를 사용합니까? var horizontal_velocity = 5

나는 최근에 우리가 물리 계산에서 피타고라스 정리를 많이 사용한다는 것을 배웠으며 실제로 포인트를 얻지 못할 것으로 두려워합니다.

다음 은 수평면에서 물체가 일정 보다 빠르게 이동하지 않도록 하는 책 의 예입니다 MAXIMUM_VELOCITY.

MAXIMUM_VELOCITY = <any number>;
SQUARED_MAXIMUM_VELOCITY = MAXIMUM_VELOCITY * MAXIMUM_VELOCITY;

function animate(){
    var squared_horizontal_velocity = (x_velocity * x_velocity) + (z_velocity * z_velocity);

    if( squared_horizontal_velocity <= SQUARED_MAXIMUM_VELOCITY ){

        scalar = squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY;

        x_velocity = x_velocity / scalar;
        z_velocity = x_velocity / scalar;
    }
}

몇 가지 숫자로 시도해 봅시다.

개체가 x 단위로 5 단위, z 단위로 5 단위를 이동하려고합니다. 총 5 대만 수평으로 움직일 수 있어야합니다!

MAXIMUM_VELOCITY = 5;
SQUARED_MAXIMUM_VELOCITY = 5 * 5;
SQUARED_MAXIMUM_VELOCITY = 25;

function animate(){
    var x_velocity = 5;
    var z_velocity = 5;

    var squared_horizontal_velocity = (x_velocity * x_velocity) + (z_velocity * z_velocity);
    var squared_horizontal_velocity = 5 * 5 + 5 * 5;
    var squared_horizontal_velocity = 25 + 25;
    var squared_horizontal_velocity = 50;

//  if( squared_horizontal_velocity <= SQUARED_MAXIMUM_VELOCITY ){
    if( 50 <= 25 ){
        scalar = squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY;
        scalar = 50 / 25;
        scalar = 2.0;

        x_velocity = x_velocity / scalar;
        x_velocity = 5 / 2.0;
        x_velocity = 2.5;

        z_velocity = z_velocity / scalar;
        z_velocity = 5 / 2.0;
        z_velocity = 2.5;

        // new_horizontal_velocity = x_velocity + z_velocity
        // new_horizontal_velocity = 2.5 + 2.5
        // new_horizontal_velocity = 5
    }
}

이제는 잘 작동하지만 피타고라스없이 동일한 작업을 수행 할 수 있습니다.

MAXIMUM_VELOCITY = 5;

function animate(){
    var x_velocity = 5;
    var z_velocity = 5;

    var horizontal_velocity = x_velocity + z_velocity;
    var horizontal_velocity = 5 + 5;
    var horizontal_velocity = 10;

//  if( horizontal_velocity >= MAXIMUM_VELOCITY ){
    if( 10 >= 5 ){
        scalar = horizontal_velocity / MAXIMUM_VELOCITY;
        scalar = 10 / 5;
        scalar = 2.0;

        x_velocity = x_velocity / scalar;
        x_velocity = 5 / 2.0;
        x_velocity = 2.5;

        z_velocity = z_velocity / scalar;
        z_velocity = 5 / 2.0;
        z_velocity = 2.5;

        // new_horizontal_velocity = x_velocity + z_velocity
        // new_horizontal_velocity = 2.5 + 2.5
        // new_horizontal_velocity = 5
    }
}

피타고라스없이 그것을 할 때의 이점 :

  1. 적은 줄
  2. 그 줄 안에서 무슨 일이 일어나고 있는지 더 쉽게 읽을 수 있습니다
  3. … 곱셈이 적기 때문에 계산 시간이 덜 걸립니다.

피타고라스 정리가 없으면 컴퓨터와 인간이 더 나은 거래를하는 것처럼 보입니다! 그러나 여러 유명한 곳에서 피타고라스의 정리를 보았을 때 내가 틀렸다고 확신하므로 피타고라스 정리를 수학 초보자 에게 사용하는 이점을 누군가에게 설명하고 싶습니다 .

이것이 단위 벡터와 관련이 있습니까? 나에게 단위 벡터는 벡터를 정규화하고 분수로 바꿀 때입니다. 벡터를 더 큰 상수로 나누면됩니다. 그것이 얼마나 일정한지 잘 모르겠습니다. 그래프의 총 크기는? 어쨌든, 분수이기 때문에 단위 벡터는 기본적으로 x 축이 -1에서 1까지, z 축이 -1에서 1까지, y가 3D 그리드 안에 들어갈 수있는 그래프입니다. 축은 -1에서 1까지입니다. 그것은 문자 그대로 단위 벡터에 대해 아는 모든 것입니다.

또한 위의 예제에서 실제로 단위 벡터를 생성하지는 않습니다. 다음과 같이 스칼라를 결정해야합니까?

// a mathematical work-around of my own invention. There may be a cleverer way to do this! I've also made up my own terms such as 'divisive_scalar' so don't bother googling
var divisive_scalar = (squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY);
var divisive_scalar = ( 50 / 25 );
var divisive_scalar = 2;

var multiplicative_scalar = (divisive_scalar / (2*divisive_scalar));
var multiplicative_scalar = (2 / (2*2));
var multiplicative_scalar = (2 / 4);
var multiplicative_scalar = 0.5;

x_velocity = x_velocity * multiplicative_scalar
x_velocity = 5 * 0.5
x_velocity = 2.5

다시 말하지만, 이것이 왜 더 좋은지 알 수 없지만 multiplicative_scalar가 unit_vector이기 때문에 더 “unit-vector-y”입니까? 보시다시피, 나는 “unit-vector-y”와 같은 단어를 사용하므로 수학은 아닙니다! 또한 단위 벡터는 피타고라스 정리와 아무 관련이 없으므로 잘못된 트리를 짖는 경우이 모든 것을 무시하십시오.

저는 매우 시각적 인 사람입니다 (무역의 3D 모델러이자 컨셉 아티스트입니다!). 도표와 그래프가 정말 인도적으로 가능한 많은 사람들에게 도움이 될 것입니다.



답변

피타고라스가없는 코드는 일반적으로 생각하는 길이를 계산하지 않습니다.

일반적으로 3D 게임에서 우리는 세계를 유클리드 공간으로 모델링하고, 유클리드 거리 측정법 ( 피타고라스 정리라고도 함 )을 사용하여 성분 vx 및 vy를 갖는 벡터 v의 총 길이를 계산합니다.

EuclideanLength(v) = sqrt(v.x * v.x + v.y * v.y)

(위의 샘플 코드에는이 제곱근이 없기 때문에 두 가지 접근 방식이 동일한 답변을 제공하는 것으로 보입니다.

위에서 설명한 코드는 Manhattan 거리 측정법을 사용합니다 .

ManhattanLength(v) = abs(v.x) + abs(v.y)

(절대 값을 포함하지 않았더라도 음수에 대해 예기치 않게 동작 할 수 있음)

vx 또는 vy가 0 일 때이 두 거리 함수가 일치한다는 것을 쉽게 알 수 있으며 한 축을 따라 움직일뿐입니다. 대각선으로 움직일 때 어떻게 비교합니까?

vx = vy = 1이라고합시다.이 벡터의 길이는 얼마입니까 (해당 속도는 얼마나 빠른가)?

Euclidean                              Manhattan

sqrt(v.x*v.x + v.y * v.y)              abs(v.x) + abs(v.y)
sqrt(1 * 1 + 1 * 1)                    abs(1) + abs(1)
sqrt(2)                                1 + 1
1.414...                               2

이러한 측정 항목이 실제로 대각선에 동의하지 않는 것을 볼 수 있습니다.

그래프에서 각 측정 항목이 원점에서 1 떨어진 거리라고하는 일련의 점을 플로팅합니다.

우리의 익숙한 유클리드 통계는 빨간색 원입니다. 이것은 x ^ 2 + y ^ 2 = 1과 같은 모든 점 x, y의 집합입니다. 회전 대칭 인 것을 알 수 있습니다. 이것이 우리가 좋아하는 이유입니다. 거리가 변하지 않는다는 생각을 깔끔하게 나타냅니다. 방향.

맨해튼 메트릭은 파란색 다이아몬드입니다. 우리의 직관적 인 거리 아이디어와는 잘 맞지 않지만 그렇게 나쁘지는 않습니다. 4 개의 기본 방향으로 별개의 단계로 이동하는 많은 타일 기반 게임에서 맨해튼 메트릭은 포인트 사이의 정확한 거리를 제공합니다 ( “도착까지 얼마나 많은 이동이 필요한가?”).

마지막으로 체비 쇼프 메트릭스 를 재미있게 던졌습니다 . 녹색 사각형입니다.

ChebyshevLength(v) = max(abs(v.x), abs(v.y))

대각선으로 움직일 수있는 타일 기반 게임에도 좋습니다. 체스의 왕은 체비 쇼프 통계에 따라 움직입니다.

전형적인 피타고라스 스타일 코드와 위에서 제공 한 예제의 차이점이 무엇인지 분명히 밝히기를 바랍니다.


답변

피타고라스가 없으면 각 축에서 고정 속도에 구속됩니다. x- 속도, y- 속도 및 (3d 세계에서) z- 속도는 모두 서로 독립적입니다. 모든 이동은이 수직 축에 정렬됩니다.

그러나 피타고라스를 사용하면 어떤 각도에서도 일정한 속도를 유지할 수 있습니다. 그러면 격자가 사라지고 물체가 가능한 모든 방향으로 일정한 속도로 움직일 수 있습니다.

피타고라스없이 물체가 1 초 안에 이동하는 부분은 다음과 같습니다 (fe Chebyshev metric)

그리고 피타고라스와 함께 :

후자는 대개 많은 경우에 훨씬 더 자연스럽게 보입니다.