Pisagor teoremini neden oyun fiziğinde kullanıyoruz?


38

Geçenlerde, Pisagor teoremini fizik hesaplamalarımızda çok kullandığımızı öğrendim ve korkarım ki gerçekten bir şey anlamadım.

Bir nesnenin yatay düzlemde sabit hızdan daha hızlı hareket etmediğinden emin olmak için bir kitaptan bir örnek 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;
    }
}

Bunu bazı sayılarla deneyelim:

Bir nesne x'te 5 birimi ve z'de 5 birimi taşımaya çalışıyor. Toplamda sadece 5 adet yatay hareket edebilmelidir!

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

Şimdi bu iyi çalışıyor, ancak Pisagor olmadan da aynı şeyi yapabiliriz:

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

Pisagor olmadan yapmanın faydaları:

  1. Daha az satır
  2. Bu satırların içinde neler olduğunu okumak daha kolay
  3. ... ve daha az çarpma olduğu için hesaplanması daha az zaman alır.

Bana göre bilgisayar ve insanlar Pisagor teoremi olmadan daha iyi bir anlaşma elde ediyorlar! Ancak, ben emin bana Pisagor teoremi bir matematik kullanmanın yararı açıklamaya biri gibi olur bu yüzden, saygın yerlerde bir dizi Pisagor teoremini gördüğümüz gibi yanılıyorum değilim acemi .

Bunun birim vektörlerle bir ilgisi var mı? Bana göre bir birim vektör, bir vektörü normalleştirip kesir haline getirdiğimiz zamandır. Bunu vektörü daha büyük bir sabitle bölerek yapıyoruz. Hangi sabit olduğundan emin değilim. Grafiğin toplam boyutu? Her neyse, çünkü bu bir kesir, sanırım, bir birim vektör temel olarak bir x-1 ile 1 arasında çalışan x-ekseni ile -1 - 1 ile 1 arasında çalışan z-ekseni ile 3B bir ızgaraya sığabilecek bir grafiktir. -axis -1'den 1'e koşuyor. Bu, birim vektörler hakkında bildiğim her şey.

Ayrıca, yukarıdaki örneklerde gerçekten bir birim vektör yaratmıyoruz. Skalleri şöyle belirleyeyim mi:

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

Yine, bunun neden daha iyi olduğunu göremiyorum, ancak multiplicative_scalar bir unit_vector olduğundan daha fazla "unit-vector-y" var? Gördüğünüz gibi, "unit-vector-y" gibi kelimeler kullanıyorum, bu yüzden gerçekten bir matematik sınavı değilim! Ayrıca birim vektörlerin Pisagor teoremiyle bir ilgisi olamayacağının farkındayım, bu yüzden yanlış ağaca havlarsam tüm bunları görmezden gelin.

Ben çok görsel bir insanım (Ticaretten 3B modeller ve konsept sanatçısıyım!) Ve diyagramları ve grafikleri gerçekten, gerçekten faydalı buluyorum, bu yüzden insanca mümkün olduğunca lütfen!


2
Aslında, doğru yazılan algoritmaların hiçbiri hızı sınırlamaz. Vektör (2.5, 2.5)değil, 5. yaklaşık 3.54 arasında bir büyüklüğe sahip olduğu
bcrist

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

1
Biz yapmıyoruz, filozof 2500 yıl önce öldü ve adını taşıyan teorem millenia henüz doğmadan önce diğer uygarlıklar tarafından anlaşıldı . Bu, Einstein'ı Neuclear denizaltılarında kullandığımız, elbette komik bir düşünce (mürettebatta bir Einstein'a sahip olan her denizci subayı) kullandığımızı söylemek gibi, ama yaptığımız şey, onun yayınladığı bir teoriyi uygulamak. Einstein örneğinde, fizikteki birçok teori ile ünlüdür, bu nedenle, kütle-enerji denkliğinin, isminin sadece bir kısmını (örneğin, "özel görelilik" yerine "görelilik") kullanarak elde ettiği teoriyi, kişi.
Andon M. Coleman

3
Konumunuzla ilgili sorun, "Pisagor olmadan aynı şeyi yapabiliriz" iddiasıdır. Ancak Manhattan mesafesi, Euclidian mesafeyle aynı değil , bu nedenle elmaları ve portakalları karşılaştırıyorsunuz. Eğer bir X / Y çifti ile Öklid mesafesini istiyorsanız , matematiği yapmanız gerekir .
Jerry B,

3
ilgili: "neden matematikte fizik kullanıyoruz" ve "neden matematikte oyun kullanıyoruz?"
vaxquis

Yanıtlar:


104

Pisagor içermeyen kodunuz, normalde düşündüğümüz bir uzunluğu hesaplamaz.

Normalde 3B oyunlarda dünyayı Öklid uzayı olarak modelliyoruz ve vx ve vy bileşenlerini içeren bir v vektörünün toplam uzunluğunu hesaplamak için bir Euclid uzaklığı ölçümü ( Pisagor Teoremi olarak da bilinir ) kullanıyoruz:

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

(Yukarıdaki örnek kodunuzda bu karekökün eksik olduğuna dikkat edin, bu yüzden iki yaklaşım aynı cevabı veriyor gibi görünmektedir.)

Tanımladığınız kod Manhattan mesafe metriğini kullanıyor :

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

(Negatif sayılar için beklenmedik şekilde davranmasını sağlayabilecek mutlak değerleri eklememiş olsanız da)

Bu iki mesafe fonksiyonunun vx veya vy sıfır olduğunda eşleştiğini görmek kolaydır ve sadece bir eksen boyunca hareket ediyoruz. Çapraz olarak hareket ettiğimizde nasıl karşılaştırırlar?

Diyelim ki vx = vy = 1. Bu vektör ne kadar sürüyor (eşdeğerde, tarif ettiği hız ne kadar hızlı)?

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

Bu metriklerin çapraz çizgiler için aslında aynı fikirde olmadığını görebilirsiniz.

Bir grafiğe, her metriğin söylediği noktadan kökene 1 mesafede olduğunu söyleyelim:

Mesafe metrikleri

Tanıdık öklid metriklerimiz kırmızı çemberdir. Bu, x, y tüm noktalarının kümesidir, öyle ki x ^ 2 + y ^ 2 = 1'dir. Dönme yönünden simetrik olduğunu görebilirsiniz, bu yüzden seviyoruz: mesafenin değişmeyeceği fikrini temsil ediyor yön.

Manhattan metriği mavi elmastır. Sezgisel uzaklık fikrimiz için harika bir eşleşme değil - ama bu onu kötü yapmaz. Dört kardinal yönde ayrık adımlarla hareket ettiğiniz birçok karo tabanlı oyunda, Manhattan metriği noktalar arasında doğru mesafeyi verir ("oraya kaç hamle yapacak?" Açısından).

Sonunda Chebyshev metrikte eğlenmek için fırlattım - yeşil kare:

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

Ayrıca köşegen üzerinde hareket etmenize izin verilen kiremit tabanlı oyunlar için de iyidir. Satrançta Bir Kral, Chebyshev metriğine göre hareket eder.

Umarım, tipik Pisagor tarzı kod ile yukarıda verdiğiniz örnek arasındaki farkın ne olduğunu temizler.


11

Pisagor olmadan, her eksende sabit bir hıza bağlanırsınız. Bir x hızına, y hızına ve (3B dünyasında) birbirinden bağımsız bir z hızına sahipsin. Herhangi bir hareket bu dik eksene göre hizalanacaktır.

Ancak, Pisagor ile, herhangi bir açıda sabit olabilen bir hıza sahipsiniz. Bu, şebekeyi ortadan kaldırmanıza ve nesnelerin herhangi bir yönde sabit bir hızla hareket etmesine izin verir.

Bir nesnenin bir saniyede harcadığı alan, Pisagor (Febyshev metrik) olmadan şöyle görünür:

görüntü tanımını buraya girin

Ve bu Pisagor ile:

görüntü tanımını buraya girin

İkincisi, çoğu durumda genellikle çok daha doğal görünür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.