Tôi đang tìm cách tạo ra chuyển động xe thực tế bằng cách sử dụng vectơ


12

Tôi đã tìm hiểu làm thế nào để làm điều này và tìm thấy http://www.rcixsoft.nl/articles/circle/sincos.htmlm Tôi đã sử dụng nó nhưng hầu hết các chức năng được hiển thị không hoạt động tôi chỉ gặp lỗi bởi vì chúng không tồn tại Tôi đã xem xét các chức năng cos và sin nhưng không hiểu cách sử dụng chúng hoặc làm thế nào để chuyển động xe hoạt động chính xác bằng vectơ. Tôi không có mã bởi vì tôi không biết phải làm gì để xin lỗi.

Bất kỳ trợ giúp được đánh giá cao.

BIÊN TẬP:

Tôi có những hạn chế rằng tôi phải sử dụng công cụ TL cho trò chơi của mình, tôi không được phép thêm bất kỳ loại công cụ vật lý nào. Nó phải được lập trình trong c ++. Đây là một ví dụ về những gì tôi đã nhận được từ việc cố gắng làm theo những gì đã được thực hiện trong liên kết tôi cung cấp.

if(myEngine->KeyHeld(Key_W))
    {
        length += carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_S))
    {
        length -= carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_A))
    {
        angle -= carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_D))
    {
        angle += carSpeedIncrement;
    }

    carVolocityX = cos(angle);
    carVolocityZ = cos(angle);

    car->MoveX(carVolocityX * frameTime);
    car->MoveZ(carVolocityZ * frameTime);

Kiểm tra trang web này để biết các hành vi chỉ đạo: red3d.com/cwr/steer
MichaelHouse

Bạn cần xác định "chuyển động xe thực tế"
Maik Semder

1
Tôi cho rằng góc của bạn đến từ tay lái, có lẽ. Độ dài phải là độ lớn của vận tốc của bạn. Vì vậy, các đoạn mã cuối cùng có thể là một cái gì đó trên dòng: carVecloityX = length* cos(angle);, carVelocityZ = length *sin(angle);, ngoài việc đó, xin vui lòng cho biết những gì đầu vào của bạn là gì và như thế nào xe nên cư xử. Ngay bây giờ, nó nên lái trong mặt phẳng mặt đất, nhưng một lần nữa, đây không phải là chung chung. Ở đó bạn vừa thực hiện cho chúng tôi một bước tích hợp Euler thô thiển ..
teodron

Câu trả lời:


23

Không khó để tạo ra một phong trào xe hơi khá tốt (nhưng bài đăng này sẽ khá dài). Bạn sẽ cần phải "mô phỏng" một vài lực cơ bản để làm cho chiếc xe chuyển động hợp lý.

(Tất cả các mẫu mã là mã giả.)

Sự tăng tốc

Đầu tiên, rõ ràng bạn sẽ cần tăng tốc. Một cái gì đó đơn giản như dòng sau sẽ làm:

acceleration_vector = forward_vector * acceleration_input * acceleration_factor
  • forward_vector - Một vectơ chỉ cùng hướng với ô tô.
  • acceleration_input - Đầu vào phải nằm trong khoảng [-1, 1].
  • acceleration_factor - Giá trị của gia tốc (pixel / giây ^ 2 hoặc bất kể đơn vị của bạn là gì).

Hệ thống lái

Chỉ đạo cũng khá đơn giản. Về nguyên tắc, những gì bạn sẽ làm là xoay vectơ về phía trước của chiếc xe để làm cho nó chỉ theo một số hướng khác.

steer_angle = steer_input * steer_factor
new_forward_vector = rotate_around_axis(forward_vector, up_vector, steer_angle)

Bạn có thể gặp một biến chứng ở đây, tuy nhiên. Nếu đầu vào của bạn thông qua bàn phím, giá trị của nó sẽ là -1 hoặc 1, có nghĩa là xe của bạn sẽ chuyển ngay lập tức. Bạn có thể khắc phục điều này bằng cách sử dụng phép nội suy tuyến tính rất đơn giản (lerping):

 amount = time_since_last_frame * steer_lerp_factor
 forward_vector = lerp(forward_vector, new_forward_vector, amount)

Số lượng phải phụ thuộc vào thời gian sao cho chuyển động của bạn không phụ thuộc vào tốc độ khung hình của bạn. Số lượng phải nằm trong khoảng [0, 1] và càng nhỏ, quá trình chuyển đổi giữa các vectơ cũ và mới sẽ càng mượt mà.

(Tại thời điểm này, bạn sẽ thấy rằng chiếc xe sẽ lái ngay cả khi nó đứng yên. Để ngăn chặn điều đó, nhân steer_anglevới current_speed / max_speed, nơi max_speedlà một hằng số được xác định bởi bạn.)

Di chuyển

Bây giờ chúng ta sẽ áp dụng khả năng tăng tốc và di chuyển chiếc xe một số pixel nhất định dựa trên vận tốc, gia tốc và khả năng lái của nó. Chúng tôi cũng sẽ muốn giới hạn tốc độ của xe sao cho nó không di chuyển quá nhanh.

current_speed = velocity_vector.norm()
if (current_speed < max_speed)
{
    velocity_vector += acceleration_vector * time_since_last_frame
}

position_vector += velocity_vector * time_since_last_frame

Xe của bạn đang trượt

Nếu tôi đúng, chiếc xe của bạn bây giờ dường như bị trượt bất cứ khi nào bạn rẽ như thể đang ở trên băng. Điều này là do không có ma sát. Trên một chiếc xe thật có ma sát bên cao (do các bánh xe không thể quay sang một bên: P).

Bạn sẽ cần phải giảm vận tốc bên. Bằng cách không giảm hoàn toàn, bạn cũng có thể làm cho chiếc xe dường như bị trôi.

 lateral_velocity = right_vector * dot(velocity_vector, right_vector)
 lateral_friction = -lateral_velocity * lateral_friction_factor 

Vì chúng ta đang nói về ma sát, bạn cũng có thể muốn có một lực (ma sát) làm giảm vận tốc của bạn để khi bạn dừng tăng tốc, cuối cùng xe của bạn sẽ dừng lại.

 backwards_friction = -velocity_vector * backwards_friction_factor

Mã của bạn để di chuyển chiếc xe bây giờ sẽ trông như thế này:

// Friction should be calculated before you apply the acceleration
lateral_velocity = right_vector * dot(velocity_vector, right_vector)
lateral_friction = -lateral_velocity * lateral_friction_factor
backwards_friction = -velocity_vector * backwards_friction_factor
velocity_vector += (backwards_friction + lateral_friction) * time_since_last_frame


current_speed = velocity_vector.norm()
if (current_speed < max_speed)
{ 
    velocity_vector += acceleration_vector * time_since_last_frame
}

position_vector += velocity_vector * time_since_last_frame

Ghi chú kết thúc

Tôi đã đề cập đến cách bạn nên áp dụng lerping để chỉ đạo; Tôi nghĩ rằng bạn có thể cần phải làm điều tương tự để tăng tốc và có thể cho góc lái (bạn sẽ phải lưu trữ giá trị của chúng từ khung trước đó và lerp từ đó). Ngoài ra tất cả các vectơ liên quan đến xe (tiến, phải, lên) nên có chiều dài 1.

Ngoài ra, ma sát phức tạp hơn một chút so với tôi chỉ ra ở đây. Bạn phải luôn đảm bảo rằng chiều dài của nó không bao giờ lớn hơn tốc độ cần thiết để khiến xe dừng lại (nếu không ma sát sẽ khiến xe chuyển động ngược chiều). Vì vậy, bạn nên có một cái gì đó như:

dt = time_since_last_frame
backwards_friction.resize(min(backwards_friction.norm(), velocity_vector.norm() / dt))
lateral_friction.resize(min(lateral_friction.norm(), lateral_velocity.norm() / dt))

Wow, đây là một câu trả lời tuyệt vời!
ezolotko

0

Đánh giá từ câu hỏi của bạn, tôi sẽ cho rằng bạn còn khá mới đối với lập trình (đó là một btw a-ok!). Tôi sẽ đề nghị sử dụng các khung hiện có vì mô phỏng xe thực tế là một trong những khía cạnh khó nhất của vật lý để có được đúng.

Bạn đã không đề cập đến các hạn chế 2D / 3D vì vậy tôi sẽ tiếp tục và đề nghị bạn tải xuống Havok SDK (miễn phí cho sử dụng phi thương mại) và tải xuống bản demo đơn giản (chúng thực sự có các bản demo chạy ra khỏi hộp [get được biên dịch trên hệ thống của bạn, tất cả các mã đều ở đó], bạn không phải làm gì để biên dịch nó ... chỉ cần mở dự án và nhấn build).

Khi bạn có một số ý tưởng về các khía cạnh đằng sau hậu trường của vật lý xe hơi (mặc dù bạn sẽ không thấy triển khai thực tế của vật lý, bị ẩn, bạn sẽ thấy các giao diện), tôi tin rằng bạn sẽ ở vị trí tốt hơn để làm cho đúng khi bạn bắt đầu một mình.

Tôi cũng đã hỏi một câu hỏi tương tự cách đây không lâu. Các liên kết trong đó cũng có thể giúp đỡ. Và đây là một liên kết khác .


Sau khi xem bản chỉnh sửa của bạn, có vẻ như bạn chỉ muốn thay đổi vận tốc của chiếc xe tùy thuộc vào các góc được tính toán (đó không phải là btw thực tế, vì vậy bạn nên thay đổi câu hỏi ban đầu để phản ánh điều đó). Nếu các góc là một phần của câu hỏi (mà bạn không thể thay đổi) và bạn phải sử dụng các góc để tính vận tốc mới, thì hãy đi với những gì @teodron đưa vào nhận xét.

Một cách khác là chỉ sử dụng vectơ. Có nhiều cách tiếp cận sử dụng vectơ, tôi sẽ trình bày một.

Vận tốc là hướng * độ lớn (trong đó độ lớn là tốc độ và hướng là vectơ chuẩn hóa). Tính tốc độ và hướng hiện tại của xe. Lấy hướng và thêm một vectơ (hãy gọi nó D') cho nó vuông góc với nó. Điều này sẽ thay đổi vận tốc của xe. Không có góc nào để lộn xộn (mặc dù bạn có thể sử dụng các góc để xác định độ dài của vectơ vuông góc có thể là yếu tố biến bạn [xem bên dưới])

Cách tính toánD' : Để tìm vectơ vuông góc, hãy lấy hướng của vận tốc ban đầu, vượt qua nó với vectơ chỉ hướng về phía màn hình trong đó thứ tự bạn vượt qua các vectơ để xác định hướng của vectơ vuông góc. Sau đó, nhiều yếu tố vuông góc này với một số yếu tố lần lượt quyết định tốc độ của chiếc xe.


Tôi sẽ nhưng tôi không được phép sử dụng một công cụ vật lý, trò chơi là 3D và tất cả những gì tôi cần thay đổi là các vectơ X và Z tôi chỉ cần tìm ra chúng là gì.
bobthemac

@bobthemac: Đây có phải là một câu hỏi bài tập về nhà? Nếu có, hãy chỉnh sửa câu hỏi của bạn để chỉ ra các hạn chế bạn có và có thể đăng một số mã có liên quan để chúng tôi có một cái gì đó để xây dựng. Btw, liên kết cuối cùng có thể là những gì bạn đang tìm kiếm về mặt hiểu biết về chức năng.
Samaursa

Tôi đã thêm thông tin bạn yêu cầu và xem các liên kết được cung cấp nhưng vẫn không hiểu.
bobthemac

@bobthemac: Xem bản chỉnh sửa của tôi
Samaursa
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.