منطقة القيد يفجر بلدي محاكاة الفيزياء إذا كان الجسم ينتقد فيه سريع جدا

StackOverflow https://stackoverflow.com/questions/1610666

سؤال

لدي محاكاة الفيزياء و انها تسمح لك لوضع المنطقة القيود ، حتى أن الهيئات داخل لا خروج هذا المجال.ومع ذلك لو ذرة يذهب الماضي واحدة من "الجدران" من المنطقة القيد فإنه يفجر محاكاة الفيزياء.لماذا يفعل هذا ؟ طريقة التحديث:

if (!atom.IsStatic)
{
    Vector2 force = Vector2.Zero;
    bool x = false, y = false;
    if (atom.Position.X - atom.Radius < _min.X)
    {
        force = new Vector2(-(_min.X - atom.Position.X), 0);
        if (atom.Velocity.X < 0)
            x = true;
    }
    if (atom.Position.X + atom.Radius > _max.X)
    {
        force = new Vector2(atom.Position.X - _max.X, 0);
        if (atom.Velocity.X > 0)
            x = true;
    }
    if (atom.Position.Y - atom.Radius < _min.Y)
    {
        force = new Vector2(0, -(_min.Y - atom.Position.Y));
        if (atom.Velocity.Y < 0)
            y = true;
    }
    if (atom.Position.Y + atom.Radius > _max.Y)
    {
        force = new Vector2(0, atom.Position.Y - _max.Y);
        if (atom.Velocity.Y > 0)
            y = true;
    }
    atom.ReverseVelocityDirection(x, y);
    if (!atom.IsStatic)
    {
        atom.Position += force;
    }
}
هل كانت مفيدة؟

المحلول 3

ولن تعلمون، بعد حوالي نصف ساعة من القرصنة الطائش في ذلك، وأنا فكرت في مجرد عدم تطبيق تصحيح الموقف. التي ثابتة وكأنه سحر. لأي المهتمة، وهنا رمز تحديث:

if (!atom.IsStatic)
{
    if (atom.Position.X - atom.Radius < _min.X && atom.Velocity.X < 0)
    {
        atom.ReverseVelocityDirection(true, false);
    }
    if (atom.Position.X + atom.Radius > _max.X && atom.Velocity.X > 0)
    {
        atom.ReverseVelocityDirection(true, false);
    }
    if (atom.Position.Y - atom.Radius < _min.Y && atom.Velocity.Y < 0)
    {
        atom.ReverseVelocityDirection(false, true);
    }
    if (atom.Position.Y + atom.Radius > _max.Y && atom.Velocity.Y > 0)
    {
        atom.ReverseVelocityDirection(false, true);
    }
}

نصائح أخرى

أرى أنك تفعل الحساب مع وقت ثابت الخطوة T.عندما النمذجة التصادم على الرغم من في كل خطوة يجب عليك استخدام الوقت خطوة يساوي الحد الأدنى من الوقت قبل أي من الذرات إلى أي عقبة.

جعل الوقت خطوة متغير, و ذرات لن "النفق" العقبات.

P. S.هناك الكثير من التحسينات في الكشف عن التصادم ، يرجى قراءة gamedev ورقات عن المعلومات.

P. S.حشرة ؟

force = new Vector2(-(_min.X - atom.Position.X), 0);

القوة يتم إنشاؤه بشكل منفصل عن X و Y التفكير.ماذا يحدث عندما ذرة يحصل في الزاوية ؟ فقط القوة الثانية سيتم تطبيقها.

P. P. S:استخدام ابسيلون

أكثر واحد ملاحظة هامة:إذا كنت تستخدم نقطة عائمة ، الخطأ المتراكمة ، و يجب استخدام eps:

abs(atom.Position.Y + atom.Radium - _max.Y) < eps

حيث eps هو عدد أصغر بكثير من الأحجام العادية في مهمتك ، على سبيل المثال0.000001.

ويبدو أنك قد حللنا المشكلة بالفعل، لكنني لاحظت أن "القوة" يبدو أن أكون مخطئا. وهي تتحرك ذرة <ط> بعيدا من الحدود، حتى لو كان على الجانب الخطأ. لنفترض ذرة وقد أطلق الماضي _max.X:

if (atom.Position.X + atom.Radius > _max.X) 
    { 
        force = new Vector2(atom.Position.X - _max.X, 0); 
        ...
    } 

والآن "القوة" سيكون في + س الاتجاه، وسوف المسافة ذرة من الجدار يتضاعف مع كل التكرار. بوم!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top