2009-10-21 21 views
5

Tôi đang xây dựng một công cụ vật lý và tôi đã có một số loại "pseudo-verlet" điều đi và tôi muốn nâng cấp nó lên "thực" verlet. Vì vậy, tôi tìm thấy một bài báo và thiết lập để làm việc. Sau khi tôi thêm vào những gì tôi nghĩ là một xấp xỉ tốt, động cơ không hoạt động nữa. Ai đó có thể giúp tôi hiểu những gì tôi đang làm sai? cập nhậtTích hợp Verlet được thổi lên động cơ vật lý của tôi

chính lớp cơ thể vật lý của tôi, áp dụng có hiệu lực, và áp dụng hệ thống xung:

public void Update(float timestepLength) 
{ 
    if (!this._isStatic) 
    { 
     Vector2 velocity = Vector2.Subtract(_position, _lastPosition); 
     Vector2 nextPos = _position + (_position - _lastPosition) + _acceleration * (timestepLength * timestepLength); 
     _lastPosition = _position; 
     _position = nextPos; 
     _acceleration = Vector2.Zero; 
    } 
} 

public void ApplyForce(Vector2 accelerationValue) 
{ 
    if (!this._isStatic) 
     _acceleration += (accelerationValue) * _mass; 
} 
public void ApplyImpulse(Vector2 impulse) 
{ 
    if (!this._isStatic) 
     _acceleration +=-1 * impulse; 
} 

Edit: Tôi đã khắc phục nó và nó hoạt động như một nét duyên dáng, nhưng tôi có hai câu hỏi về mã sau:

  • Mã ứng dụng xung có chính xác không và nếu không phải là mã nào?
  • Làm cách nào để thay đổi thuộc tính vị trí để cài đặt giữ nguyên vận tốc hiện tại của cơ thể?

Đây là mã:

public Vector2 Position 
{ 
    get { return _position; } 
    set { _position = value;} 
} 
public void Update(float timestepLength) 
{ 
    if (!this._isStatic) 
    { 
     Vector2 velocity = Vector2.Subtract(_position, _lastPosition); 
     Vector2 velocityChange = Vector2.Subtract(velocity, Vector2.Subtract(_lastPosition, _twoStepsAgoPosition)); 
     Vector2 nextPos = _position + (_position - _lastPosition) + _acceleration * (timestepLength * timestepLength); 
     _twoStepsAgoPosition = _lastPosition; 
     _lastPosition = _position; 
     _position = nextPos; 
     _acceleration = Vector2.Multiply(velocityChange, timestepLength); 
    } 
} 

public void ApplyForce(Vector2 force) 
{ 
    if (!this._isStatic) 
     _lastPosition -= force; 
} 
public void ApplyImpulse(Vector2 impulse) 
{ 
    if (!this._isStatic) 
     _acceleration +=-1 * impulse; 
} 
+0

Tại sao không: _acceleration - = xung; ? –

+0

Actualy không nghĩ về điều đó ... Cảm ơn! – RCIX

Trả lời

3

như một tài liệu tham khảo cho những người khác ... giấy verlet bạn có lẽ đề cập đến là: advanced character physics thực hiện bởi nhóm người đã tạo ra hitman và là một trong những đầu tiên đã ragdoll dựa vật lý

dù sao đi nữa ... mã gốc họ sử dụng là:

void ParticleSystem::Verlet() { 
     for(int i=0; i<NUM_PARTICLES; i++) { 
      Vector3& x = m_x[i]; 
      Vector3 temp = x; 
      Vector3& oldx = m_oldx[i]; 
      Vector3& a = m_a[i]; 
      x += x-oldx+a*fTimeStep*fTimeStep; 
      oldx = temp; 
     } 
} 

và bạn r ight rằng mã của bạn làm một điều tương tự.

Điều duy nhất làm nổ tung mô phỏng của tôi là sử dụng dấu thời gian quá lớn. Ngoài ra, với tích hợp verlet này, hãy đảm bảo rằng timestep bạn sử dụng không đổi trong suốt trò chơi. (ví dụ: 30 khung hình/giây (ví dụ: timestep là 1/30)) và không dao động. Nếu có bạn nên sử dụng time corrected verlet integration chiếm này

EDIT:

câu trả lời cho question2: để di chuyển vị trí của bạn (mà không thay đổi vận tốc/tốc) chỉ cập nhật vị trí đến vị trí mới, và sau đó là một thêm bước thêm đồng bằng của movment này (vì vậy newPosition-oldPosition) vào oldposs, do đó, điều này được cập nhật cho phù hợp.

câu trả lời cho câu hỏi1: Xung là lực được áp dụng cho một đối tượng trong một khoảng thời gian. Vì vậy, giải pháp của bạn là không chính xác. Xung sẽ là trên X timesteps (hoặc khung), bạn gọi hàm applyForce của bạn với một lực cố định.

+0

Tôi đang sử dụng http://www.gamedev.net/reference/programming/features/verlet/ làm cơ sở. Điều gì xảy ra là các hạt không thực sự di chuyển ở tất cả (dưới một lực hấp dẫn tuyến tính), và nếu tôi thay thế '_acceleration = Vector2.Zero;' dòng với _acceleration = Vector2.Multiply (_acceleration, 1 - _linearDrag); nó hoạt động rất bất thường (các hạt bắt đầu di chuyển sau đó khi chúng va vào một ràng buộc buộc chúng vào một khu vực chúng đi ra khỏi màn hình, tôi nghi ngờ các giá trị của chúng được đặt thành NaN ngay sau đó). – RCIX

+0

Tôi đang sử dụng BTW thời gian hiệu chỉnh thời gian. – RCIX

+0

Ok bây giờ tôi đã cập nhật mã và câu hỏi của mình. – RCIX

Các vấn đề liên quan