2011-03-14 6 views
1

다음 문제를 진단하는 데 문제가 있습니다.C# : Object overshoots target

두 개의 대상, 즉 반지와 대상이 있습니다. 반지는 배를 나타내고 대상은 대상을 나타냅니다. 사용자가 창에서 아무 곳이나 클릭하면 대상이 클릭 한 위치에 놓이고 우주선은 그 위치로 이동합니다. 내가 가지고있는 문제는 더 많은 우주선이 움직여야 할 때, 더 많은 속도의 우주선이 달성되어 목표물을 초과하는 것이다. 배가 더 멀리 움직일수록 감속이 느려집니다. 나는 이것이 어디에서 일어나고 있는지 확신하지 못한다. 나는 코드 아래에 제공 한 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 

namespace ArtificialDumb 
{ 
    class PhysicsObject 
    { 
     public Vector2 Position; 
     public Vector2 OldPosition; 

     public float Mass; 

     public Vector2 Acceleration; 

     public float Drag = 0.01f; 

     public PhysicsObject(float x, float y) 
     { 
      Position = OldPosition = new Vector2(x, y); 
     } 

     public PhysicsObject(Vector2 pos) 
     { 
      Position = OldPosition = pos; 
     } 

     public virtual void Update() 
     { 
      Vector2 velocity = Position - OldPosition; 

      velocity *= (1 - Drag); 

      OldPosition = Position; 
      Position += velocity; 

      Position += Acceleration; 
     } 
    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 

namespace ArtificialDumb 
{ 
    class Ship : PhysicsObject 
    { 
     public float MaxThrust; 

     public Vector2 Target; 

     public Ship(Vector2 pos) 
      : base(pos) 
     { 
      MaxThrust = 50f; 
      Mass = 100; 
     } 

     public override void Update() 
     { 
      Vector2 diff = Target - Position; 
      Vector2 Velocity = (Position - OldPosition); 


      // Dark Magic. Do Not Touch. 
      // This is the equation for projectile velocity. -ASR 
      // Edited for correct float value -ASR 
      // people keep touching! - AgH 
      Vector2 thrust = diff - (Velocity * Velocity.Length() * 0.75f); 

      thrust.Normalize(); 
      // todo: Account for when we don't need to use maximum thrusters 
      thrust *= MaxThrust; 

      Acceleration = thrust/Mass; 
      base.Update(); 
     } 
    } 
} 
+0

동일한 프로젝트입니까? http://stackoverflow.com/questions/5291667/why-isnt-my-3d-collision-detection-working –

+7

Position + = Acceleration에서 읽는 것을 중단했습니다. Isaac 경이 큰 소리로 기침 한 줄 알았습니다. 물리 모델을 수정하십시오. –

+0

@Hans 다행히 당신을 위해 나는 의견을 downvote 수 없습니다. 틀림없이 구현은 좀 이상하지만 그의 물리학은 완전히 건전하다. 속도는 (pos-oldPos)로 계산되므로 위치에 직접 가속도를 추가하면 속도에 영향을줍니다. 이것의 이점은 위치가 외부 적으로 (예를 들어 충돌 후) 바뀔 때 속도가 자동으로 조정된다는 것입니다. – Hannesh

답변

2

이것은 생각보다 덜 사소한 것입니다. 힘들게 만드는 이유는 배가 0 속도로 올바른 위치에 오게해야한다는 것입니다.

올바른 일을하고 수학을 두려워하지 않으려면 PID controller을 구현하십시오. 이러한 종류의 문제를 해결하는 표준 방법입니다. 자동 조종 장치와 같은 것들은 종종 업계에서 널리 사용되고 있습니다.

그러나 쉬운 방법이 있습니다.

이미 목표를 향해 곧장 여행하는 경우 지금 감속을 시작한 경우 어디로 갈 것인지 계산할 수 있습니다. 당신의 감속을 가정 은 일정 : 지금 제동을 시작하는 경우가 끝날 것 곳

endPos = Position + (Velocity * Velocity)/(2 * deceleration); 

endpos는입니다. 타겟과 비교하여 현재 오버 슛 또는 언더 슛 여부를 확인할 수 있습니다.

당신은 당신이 브레이크에 필요, 당신은 위의 공식 재 배열에 의해 당신이 당신의 목표에 도달하기 위해 브레이크 할 필요가 정확히 얼마나 계산할 수 있습니다 알고있는 경우 :

deceleration = (Velocity * Velocity)/(2 * (endPos - Position)); 

여기 감속 인 '추진력'을 그 당신은 당신이 그것을 원하는 곳에서 멈추도록 당신의 배를 줄 필요가 있습니다.

이 정보가 도움이되기를 바랍니다. 이해가되지 않거나 위의 수식이 어떻게 생겼는지에 대한 설명을 원합니다.

0

이 물리 시뮬레이션과 일반적인 문제입니다. 모든 업데이트에 대해 마지막으로 알려진 위치에서 현재 위치까지의 경로를 확인하십시오. 도중에 어떤 도형이 있으면 충돌했음을 알 것입니다.

그 시점에서 반응 방법을 선택할 수 있습니다. Farseer과 같은 많은 물리 라이브러리는 실제로 오브젝트를 충돌 지점으로 이동시킨 다음 거기에서 반응 (바운스, 스핀 등)을 발생시킵니다.