4

私は C# と Winforms を使用して (一種の) 重力シミュレーションに取り組んでいますが、非常に奇妙な動作が発生しています。クリックするとオブジェクトが作成され、他のオブジェクトに引き付けられます。問題は、それらが変な距離内にない限り、正の方向 (右、下) に引き寄せられず、上と左に引き寄せられることです。

これは更新コードです:

    public Vector GetGravEffect(GravObject other)
    {
        if ((Math.Abs(X - other.X) <= Mass * Form.DrawScale + other.Mass * Form.DrawScale) && 
            (Math.Abs(Y - other.Y) <= Mass * Form.DrawScale + other.Mass * Form.DrawScale))
        {
            return new Vector(0, 0);
        }

        double tAngle = Math.Atan2((other.Y - Y), (other.X - X));

        double tMagnitude = (GravModifier * Mass * other.Mass / ((Math.Pow((other.X - X), 2)) + (Math.Pow((other.Y - Y), 2))) * 1000);

        Complex c = Complex.FromPolarCoordinates(tMagnitude, tAngle);

        Vector r = new Vector(c.Real, c.Imaginary);

        return r;
    }

完全なコードはこちら: https://docs.google.com/open?id=0B79vmyWxBr-kTnUtQURPUlVidzQ

助けてくれてありがとう!

4

1 に答える 1

5

問題は GetGravEffect メソッド (正しい結果が得られる) ではなく、Update メソッドにあります。物理法則を完全に無視しています。GetGravEffect によって返される値を合計して速度と見なすことはできません。GetGravEffect は、一方のオブジェクトが他方を引き付ける力を返します。これらの力を合計し、慣性、加速度、時間を含む追加の計算を行って、結果の速度を計算する必要があります。また、X と Y を int にキャストすることは、特に速度が遅い場合に精度が大幅に低下するため、お勧めできません。次の修正された方法を使用すると、うまく機能します。

    public void Update() {
        Vector Force = new Vector(0, 0);
        foreach (GravObject g in Form.Objects) {
            if (this != g)
                Force += GetGravEffect(g);
        }

        double TimeElapsedSinceLastUpdate = Form.Timer.Interval * 0.001;
        Vector acceleration = Force / Mass;
        Velocity += acceleration*TimeElapsedSinceLastUpdate;

        X = (X + Velocity.X * Form.VelocityScale);
        Y = (Y + Velocity.Y * Form.VelocityScale);

        if (X + Mass * Form.DrawScale >= Form.Panels.Panel2.Width || X - Mass * Form.DrawScale <= 0)
            Velocity.X *= -1;
        if (Y + Mass * Form.DrawScale >= Form.Panels.Panel2.Height || Y - Mass * Form.DrawScale <= 0)
            Velocity.Y *= -1;
    }
于 2012-05-20T03:17:21.417 に答える