Dlaczego używamy twierdzenia Pitagorasa w fizyce gry?


38

Niedawno dowiedziałem się, że często używamy twierdzenia Pitagorasa w naszych obliczeniach fizycznych i obawiam się, że tak naprawdę nie rozumiem.

Oto przykład z książki, aby upewnić się, że obiekt nie porusza się szybciej niż MAXIMUM_VELOCITYstała w płaszczyźnie poziomej:

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;
    }
}

Spróbujmy tego z kilkoma liczbami:

Obiekt próbuje przesunąć 5 jednostek w x i 5 jednostek w z. Łącznie powinno być w stanie przesunąć tylko 5 jednostek w poziomie!

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
    }
}

Teraz działa to dobrze, ale możemy zrobić to samo bez Pitagorasa:

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
    }
}

Korzyści z robienia tego bez Pitagorasa:

  1. Mniej linii
  2. W tych liniach łatwiej jest przeczytać, co się dzieje
  3. ... a obliczenie zajmuje mniej czasu, ponieważ jest mniej mnożników

Wydaje mi się, że komputery i ludzie mają lepszą ofertę bez twierdzenia Pitagorasa! Jestem jednak pewien, że się mylę, ponieważ widziałem twierdzenie Pitagorasa w wielu renomowanych miejscach, dlatego chciałbym, aby ktoś wyjaśnił mi korzyści płynące z zastosowania twierdzenia Pitagorasa nowicjuszowi z matematyki .

Czy to ma coś wspólnego z wektorami jednostkowymi? Dla mnie wektorem jednostkowym jest normalizacja wektora i przekształcenie go w ułamek. Robimy to, dzieląc wektor przez większą stałą. Nie jestem pewien, jaka to stała. Całkowity rozmiar wykresu? W każdym razie, ponieważ jest to ułamek, rozumiem, wektor jednostkowy jest w zasadzie wykresem, który może zmieścić się w siatce 3D z osią x od -1 do 1, osią z od -1 do 1, a y - oś biegnie od -1 do 1. To dosłownie wszystko, co wiem o wektorach jednostkowych ... niewiele: P I nie widzę ich przydatności.

Ponadto tak naprawdę nie tworzymy wektora jednostkowego w powyższych przykładach. Czy powinienem określać skalar w ten sposób:

// 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

Ponownie nie rozumiem, dlaczego jest to lepsze, ale jest to bardziej „wektor-jednostka-y”, ponieważ multiplikatywny_skalar to wektor_jednostkowy? Jak widać, używam słów takich jak „jednostka-wektor-y”, więc tak naprawdę nie jestem matematyką! Wiedz też, że wektory jednostkowe mogą nie mieć nic wspólnego z twierdzeniem Pitagorasa, więc zignoruj ​​to wszystko, jeśli szczekam na niewłaściwym drzewie.

Jestem osobą bardzo wizualną (modelarz 3D i artysta koncepcyjny z zawodu!) I uważam, że diagramy i wykresy są naprawdę, bardzo pomocne, więc jak najwięcej ludzi proszę!


2
W rzeczywistości żaden z poprawnie napisanych algorytmów nie ogranicza prędkości. Wektor (2.5, 2.5)ma wielkość około 3,54, a nie 5
bcrist

1
sqrt(2.5*2.5 + 2.5*2.5)
bcrist

1
My nie, filozof zmarł 2500 lat temu, a twierdzenie, które nosi jego imię, zostało zrozumiane przez inne cywilizacje jeszcze przed tysiącleciem . To trochę tak, jakby powiedzieć, że używamy Einsteina w okrętach podwodnych Neuclear, co na pewno jest zabawne (każdy okręt podwodny ma Einsteina w załodze), ale stosujemy częściowo teorię, którą opublikował. W przypadku Einsteina jest on znany z wielu teorii w fizyce, więc można nazwać teorię, z której pochodzi równoważność masy i energii, używając tylko części jej nazwy (np. „Względność” zamiast „szczególna teoria względności”), nie myląc jej osoba.
Andon M. Coleman

3
Problem z twoją pozycją polega na twierdzeniu, że „możemy zrobić to samo bez Pitagorasa”. Ale odległość na Manhattanie nie jest taka sama jak odległość euklidesowa, więc porównujesz jabłka i pomarańcze. Jeśli chcesz odległość euklidesową z parą X / Y, to mają zrobić matematyki.
Jerry B

3
powiązane: „dlaczego używamy matematyki w fizyce” i „dlaczego używamy matematyki w grach?”
vaxquis

Odpowiedzi:


104

Twój kod wolny od Pitagorasa nie oblicza długości, jak zwykle o tym myślimy.

Zwykle w grach 3D modelujemy świat jako przestrzeń euklidesową i używamy metryki odległości euklidesowej ( znanej również jako twierdzenie Pitagorasa ) do obliczenia całkowitej długości wektora v ze składnikami vx i vy Mianowicie:

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

(Zwróć uwagę, że w powyższym przykładowym kodzie brakuje tego pierwiastka kwadratowego, dlatego wydaje się, że te dwa podejścia dają tę samą odpowiedź. Więcej na ten temat wkrótce ...)

Opisany kod wykorzystuje metrykę Manhattan :

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

(Chociaż nie podałeś wartości bezwzględnych, co może powodować, że będzie się zachowywał nieoczekiwanie w przypadku liczb ujemnych)

Łatwo zauważyć, że te dwie funkcje odległości pasują do siebie, gdy vx lub vy wynosi zero, a my poruszamy się tylko wzdłuż jednej osi. Jak się jednak porównują, kiedy poruszamy się po przekątnej?

Powiedzmy, że vx = vy = 1. Jak długi jest ten wektor (równoważnie, jak duża jest prędkość, którą opisuje)?

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

Widać, że te dane w rzeczywistości nie są zgodne dla linii ukośnych.

Narysujmy na wykresie zbiór punktów, które według każdej metryki są w odległości 1 od początku:

Wskaźniki odległości

Naszą znaną miarą euklidesową jest czerwone kółko. Jest to zbiór wszystkich punktów x, y takich, że x ^ 2 + y ^ 2 = 1. Widać, że jest obrotowo-symetryczny i dlatego nam się podoba: dobrze reprezentuje ideę, że odległość nie zmienia się przy kierunek.

Metryka na Manhattanie to niebieski diament. Niezbyt pasuje do naszego intuicyjnego pomysłu odległości - ale to nie jest złe. W wielu grach opartych na kafelkach, w których poruszasz się w dyskretnych krokach w czterech głównych kierunkach, metryka Manhattanu podaje prawidłową odległość między punktami (pod względem „ile ruchów potrzeba, aby się tam dostać?”)

Wreszcie dla zabawy wrzuciłem metrykę Czebyszewa - to zielony kwadrat:

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

Jest również dobry w grach opartych na kafelkach, w których możesz poruszać się po przekątnych. Król w szachach porusza się zgodnie z miarą Czebyszewa.

Mam nadzieję, że to wyjaśni różnicę między typowym kodem w stylu pitagorejskim a przykładem podanym powyżej.


11

Bez Pitagorasa jesteś związany stałą prędkością na każdej osi. Masz prędkość x, prędkość y oraz (w świecie 3d) prędkość z, które są od siebie niezależne. Każdy ruch zostanie wyrównany do tych prostopadłych osi.

Jednak w przypadku Pitagorasa masz prędkość, która może być stała pod dowolnym kątem. To pozwala sprawić, że siatka zniknie, a obiekty będą poruszać się ze stałą prędkością w dowolnym możliwym kierunku.

Obszar, w którym obiekt przemieszcza się w ciągu jednej sekundy, wygląda tak bez Pitagorasa (np. Metryka Czebyszewa):

wprowadź opis zdjęcia tutaj

A to z Pitagorasem:

wprowadź opis zdjęcia tutaj

Ta ostatnia zwykle wydaje się w wielu przypadkach znacznie bardziej naturalna.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.