我无法诊断出以下问题。
有2个物体,一个戒指和一个目标。环表示船舶,目标表示目的地。当用户单击窗口中的任意位置时,目标将放置在您单击的位置,然后该船将移动到该位置。我遇到的问题是船舶必须移动的距离越远,船舶将达到的速度越快,从而超越其目标。船舶必须进一步移动转换为较慢的减速度。我不确定这是怎么回事。我提供了以下代码:
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 :(得分:2)
这不像看起来那么简单。难以置信的是,你必须让你的船以0速度结束在正确的位置。
如果你想做得好并且不怕数学,那就实施PID controller。这是解决这类问题的标准方法。对于像自动驾驶仪这样的事情,它在业内经常出现。
然而,有一种更简单的方法!
如果您已经直接朝目标前进,那么如果您现在开始减速,您可以计算最终结果。 假设你的减速度是恒定的:
endPos = Position + (Velocity * Velocity) / (2 * deceleration);
如果你现在开始制动,那么你最终会到达endPos。您可以将其与目标进行比较,以查看您当前是否超调或下冲。
如果您知道需要刹车,可以通过重新排列上述公式来精确计算制动到达目标的准确程度:
deceleration = (Velocity * Velocity) / (2 * (endPos - Position));
这里的减速是你需要让你的船停在你想要的地方的“推力”。
我希望这会有所帮助,如果您不理解任何内容,请告诉我,或者想要解释我如何提出上述公式。
答案 1 :(得分:0)
这是物理模拟的常见问题。您要做的是,对于每次更新,检查从上一个已知位置到当前位置的路径。如果路上有任何几何形状,你知道你应该碰撞。
此时您可以选择如何反应。像Farseer这样的许多物理库实际上会将物体移回碰撞点,然后让反应(反弹,旋转等)从那里发生