使用Verlet方法在unity2d中绘制土耳其

时间:2019-07-13 00:58:24

标签: c# unity3d verlet-integration

这是一个作业问题(请勿复制,复制不明智):我们需要使用Verlet方法以统一2d方式绘制2d火鸡以更新顶点的位置。但是,我们不知道追踪土耳其的势力。这是土耳其的照片。有把戏吗? enter image description here

这是我们开始的代码:

Setter<BorderValues>, so you want to call

1 个答案:

答案 0 :(得分:0)

由于轮廓不匹配,我不确定我是否正确决定了,但是在解决方案中速度是完全迭代的。我认为这是Unity物理上的一个小错误,因为如果使用所产生的加速度,则可以非常精确地绘制图形。

enter image description here

这是代码:

public class Drawer : MonoBehaviour
{
    [SerializeField]
    private Transform[] m_Dots;

    private Rigidbody2D m_Dot;
    private Vector2[] m_Acceler;
    float deltaT = 0.5f;//for example

    private void Start()
    {
        m_Acceler = GetAcceler();

        var go = new GameObject("Tracer");
        var tr = go.AddComponent<TrailRenderer>();
        tr.widthMultiplier = 0.1f;
        tr.time = 50f;
        m_Dot = go.AddComponent<Rigidbody2D>();
        m_Dot.bodyType = RigidbodyType2D.Kinematic;
        m_Dot.gravityScale = 0;

        StartCoroutine(VerletCoroutine());
    }

    private Vector2[] GetAcceler()
    {
        Vector2[] result = new Vector2[m_Dots.Length];
        float T = deltaT;

        int len = m_Dots.Length;
        result[0] = An(m_Dots[1].position, m_Dots[0].position, m_Dots[0].position, T);
        for (int i = 1 ; i < len - 1 ; i++, T += deltaT)
        {
            result[i] = An(m_Dots[i + 1].position, m_Dots[i].position, m_Dots[i].position, T);
        }

        result[len - 1] = An(m_Dots[0].position, m_Dots[len - 1].position, m_Dots[len - 1].position, T);
        return result;
    }

    private Vector2 An(Vector2 Xnext, Vector2 Xn, Vector2 Xprev, float t)
    {// a[n] = (x[n+1] - 2*x[n]+x[n-1])/t^2
        return (Xnext - 2 * Xn + Xprev) / t * t;
    }

    private IEnumerator VerletCoroutine()
    {
        m_Dot.transform.position = m_Dots[0].position;
        Vector2 Vprev = Vector2.zero;
        int len = m_Acceler.Length - 1;
        float t = 0;
        int i = 0;
        while (true)
        {
            t += Time.deltaTime;
            if (t >= deltaT)
            {
                i++;
                if (i > len)
                {
                    break;
                }
                t = 0;
                Vprev = Vector2.zero;
            }
            Vprev = Vnext(Vprev, m_Acceler[i], m_Acceler[i], t);
            m_Dot.velocity = Vprev;
            yield return new WaitForEndOfFrame();
        }
        m_Dot.velocity = Vector3.zero;
        yield return null;
    }

    private Vector2 Vnext(Vector2 Vn, Vector2 Anext, Vector2 An, float t)
    {//v[n+1]= v[n]+0,5(a[n+1] +a[n]) * t
        var v = Vn + 0.5f * (Anext + An) * t;
        return v;
    }
}