Tại sao chúng ta sử dụng định lý Pythagore trong vật lý trò chơi?


38

Gần đây tôi đã biết rằng chúng tôi sử dụng định lý Pythagore rất nhiều trong các tính toán vật lý của chúng tôi và tôi sợ rằng tôi không thực sự hiểu được.

Dưới đây là một ví dụ từ một cuốn sách để đảm bảo một vật thể không di chuyển nhanh hơn MAXIMUM_VELOCITYhằng số trong mặt phẳng ngang:

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

Hãy thử điều này với một số con số:

Một đối tượng đang cố gắng di chuyển 5 đơn vị theo x và 5 đơn vị theo z. Nó chỉ có thể di chuyển tổng cộng 5 đơn vị theo chiều ngang!

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

Bây giờ điều này hoạt động tốt, nhưng chúng ta có thể làm điều tương tự mà không cần Pythagoras:

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

Lợi ích của việc làm mà không cần Pythagoras:

  1. Ít dòng
  2. Trong những dòng đó, việc đọc những gì đang diễn ra sẽ dễ dàng hơn
  3. ... và mất ít thời gian hơn để tính toán, vì có ít phép nhân hơn

Dường như với tôi như máy tính và con người có được một thỏa thuận tốt hơn mà không cần định lý Pythagore! Tuy nhiên, tôi chắc chắn rằng tôi đã sai khi tôi thấy định lý của Pythagoras ở một số nơi có uy tín, vì vậy tôi muốn ai đó giải thích cho tôi lợi ích của việc sử dụng định lý Pythagore cho một người mới học toán .

Điều này có liên quan gì đến vectơ đơn vị không? Đối với tôi một vectơ đơn vị là khi chúng ta bình thường hóa một vectơ và biến nó thành một phần. Chúng tôi làm điều này bằng cách chia vectơ cho một hằng số lớn hơn. Tôi không chắc nó là gì. Tổng kích thước của đồ thị? Dù sao, vì nó là một phân số, tôi lấy nó, một vectơ đơn vị về cơ bản là một biểu đồ có thể nằm gọn trong lưới 3D với trục x chạy từ -1 đến 1, trục z chạy từ -1 đến 1 và y -axis chạy từ -1 đến 1. Đó thực sự là tất cả những gì tôi biết về vectơ đơn vị ... không nhiều: P Và tôi không thấy được sự hữu ích của chúng.

Ngoài ra, chúng tôi không thực sự tạo ra một vectơ đơn vị trong các ví dụ trên. Tôi có nên xác định vô hướng như thế này không:

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

Một lần nữa, tôi không thể thấy lý do tại sao điều này tốt hơn, nhưng đó là "đơn vị-vector-y" nhiều hơn bởi vì phép nhân_scalar là một đơn vị? Như bạn có thể thấy, tôi sử dụng các từ như "đơn vị-vector-y" vì vậy tôi thực sự không phải là một nhà toán học! Cũng lưu ý rằng các vectơ đơn vị có thể không liên quan gì đến định lý Pythagore vì vậy hãy bỏ qua tất cả những điều này nếu tôi sủa sai cây.

Tôi là một người rất trực quan (người điều hành 3D và nghệ sĩ khái niệm bằng thương mại!) Và tôi thấy sơ đồ và đồ thị thực sự, thực sự hữu ích để nhiều người có thể làm ơn!


2
Trên thực tế, cả hai thuật toán như được viết đều giới hạn vận tốc. Vectơ (2.5, 2.5)có cường độ xấp xỉ 3,54, không phải 5.
bcrist

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

1
Chúng tôi không, các nhà triết học đã chết cách đây 2.500 năm và định lý mang tên ông được hiểu bởi nền văn minh khác thiên niên kỷ trước khi ông được sinh ra. Điều đó giống như việc chúng ta sử dụng Einstein trong các tàu ngầm hạt nhân, một ý nghĩ hài hước chắc chắn (mọi phụ có Einstein trong phi hành đoàn), nhưng những gì chúng ta làm là áp dụng một phần lý thuyết mà ông đã xuất bản. Trong trường hợp của Einstein, ông nổi tiếng với nhiều lý thuyết trong vật lý, do đó bạn có thể đặt tên cho lý thuyết mà từ đó năng lượng tương đương khối lượng được lấy bằng cách chỉ sử dụng một phần tên của nó (ví dụ "thuyết tương đối" thay vì "thuyết tương đối đặc biệt") mà không nhầm lẫn nó với người.
Andon M. Coleman

3
Vấn đề với vị trí của bạn là tuyên bố rằng "chúng ta có thể làm điều tương tự mà không cần Pythagoras". Nhưng khoảng cách Manhattan không giống với khoảng cách Euclidian, vì vậy bạn đang so sánh táo và cam. Nếu bạn muốn khoảng cách Euclide từ một cặp X / Y, bạn phải làm toán.
Jerry B

3
có liên quan: "tại sao chúng ta sử dụng toán học trong vật lý" và "tại sao chúng ta sử dụng toán học trong các trò chơi?"
vaxquis

Câu trả lời:


104

Mã không có Pythagoras của bạn không tính toán độ dài như chúng ta thường nghĩ về nó.

Thông thường trong các trò chơi 3D, chúng tôi mô hình hóa thế giới dưới dạng không gian Euclide và chúng tôi sử dụng thước đo khoảng cách Euclide ( còn được gọi là Định lý Pythagore ) để tính tổng chiều dài của vectơ v với các thành phần vx và vy Cụ thể:

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

(Lưu ý rằng căn bậc hai này bị thiếu trong mã mẫu của bạn ở trên, đó là lý do tại sao hai cách tiếp cận dường như đưa ra cùng một câu trả lời. Thêm vào đó ngay sau đó ...)

Mã bạn đã mô tả sử dụng số liệu khoảng cách Manhattan :

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

(Mặc dù bạn không bao gồm các giá trị tuyệt đối, điều này có thể khiến nó hoạt động bất ngờ đối với các số âm)

Thật dễ dàng để thấy rằng hai hàm khoảng cách này khớp với nhau khi vx hoặc vy bằng 0 và chúng ta chỉ di chuyển dọc theo một trục. Làm thế nào để họ so sánh mặc dù khi chúng ta di chuyển theo đường chéo?

Giả sử vx = vy = 1. Vectơ này dài bao nhiêu (tương đương, tốc độ mà nó mô tả) nhanh như thế nào?

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

Bạn có thể thấy những số liệu này không thực sự đồng ý cho các đường chéo.

Hãy vẽ biểu đồ trên tập hợp các điểm mà mỗi số liệu cho biết cách điểm gốc 1 khoảng cách:

Số liệu khoảng cách

Số liệu Euclide quen thuộc của chúng tôi là vòng tròn màu đỏ. Đây là tập hợp tất cả các điểm x, y sao cho x ^ 2 + y ^ 2 = 1. Bạn có thể thấy rằng nó đối xứng xoay và đó là lý do tại sao chúng tôi thích nó: nó thể hiện gọn gàng ý tưởng rằng khoảng cách không thay đổi theo phương hướng.

Số liệu Manhattan là viên kim cương màu xanh. Không phải là một kết hợp tuyệt vời cho ý tưởng trực quan của chúng ta về khoảng cách - nhưng điều đó không làm cho nó xấu. Trong nhiều trò chơi dựa trên ô xếp mà bạn di chuyển theo các bước riêng biệt theo bốn hướng chính, số liệu Manhattan cho khoảng cách chính xác giữa các điểm (theo cách "sẽ mất bao nhiêu di chuyển để đến đó?")

Cuối cùng, tôi đã ném vào số liệu Ch Quashev cho vui - đó là hình vuông màu xanh lá cây:

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

Nó cũng tốt cho các trò chơi xếp gạch, nơi bạn được phép di chuyển trên các đường chéo. Một vị vua trong cờ vua di chuyển theo số liệu Ch Quashev.

Tôi hy vọng rằng sẽ làm rõ sự khác biệt giữa mã kiểu Pythagore điển hình và ví dụ bạn đã cung cấp ở trên.


11

Không có Pythagoras, bạn bị ràng buộc với một vận tốc cố định trên mỗi trục. Bạn có tốc độ x, tốc độ y và (trong thế giới 3d) tốc độ z hoàn toàn độc lập với nhau. Bất kỳ chuyển động sẽ được liên kết với các trục vuông góc.

Tuy nhiên, với Pythagoras, bạn có tốc độ không đổi ở mọi góc độ. Điều đó cho phép bạn làm cho lưới biến mất và có các vật thể chuyển động với tốc độ không đổi theo bất kỳ hướng nào có thể.

Khu vực mà một vật thể di chuyển trong một giây trông như thế này mà không có Pythagoras (số liệu của Ch Chshshev):

nhập mô tả hình ảnh ở đây

Và điều này với Pythagoras:

nhập mô tả hình ảnh ở đây

Thứ hai thường có vẻ tự nhiên hơn nhiều trong nhiều trường hợp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.