English 中文(简体)
• 如何避免与Verlet的融合者发生时间变化时的意外额外速度
原标题:How to avoid undesired additional velocity from time step change with Verlet integrator

我知道这个标题是一个目击器,但主要是一个副作用的问题。 我能用数学一夫学习我的物理类别。 它有2Dbouncing ball app。 我用经过更正的Verlet综合器,在地板上注入冲力,是屏幕的底层。 I m 添加摩擦和oun,使球最终达到0速度。

问题表明,当篮子停在地板上,“重大”时步发生变化。 集成商无节制地调整了电流,最终向地上发射冲动。 速率大于2.5的豆类火灾。 甲型六氯环己烷通常造成经过调整的18年速度。

感谢任何帮助。 我认识到法典结构可能更好,但我只想视和运用物理学。 谢谢。

// The loop
public void run() {
    if(mRenderables != null) {
        final long time = SystemClock.uptimeMillis();
       final long timeDelta = time - mLastTime;

        if(mLastTime != 0) {
            final float timeDeltaSeconds = timeDelta / 1000.0f; 

            if(mLastTimeDeltaSec != 0) {                    
                for(short i = 0; i < mRendLength; i++) {
                    Ball b1 = mRenderables[i];

                    // Acceleration is gauged by screen s tilt angle
                    final float gravityX = -mSV.mSensorX * b1.MASS;
                    final float gravityY = -mSV.mSensorY * b1.MASS;

                    computeVerletMethod(b1, gravityX, gravityY, timeDeltaSeconds, mLastTimeDeltaSec);
                }
            }

            mLastTimeDeltaSec = timeDeltaSeconds;
        }

        mLastTime = time;
    }
}

/*
* Time-Corrected Verlet Integration
* xi+1 = xi + (xi - xi-1) * (dti / dti-1) + a * dti * dti
*/  
public void computeVerletMethod(Renderable obj, float gravityX, float gravityY, float dt, float lDT) {
    mTmp.x = obj.pos.x;
    mTmp.y = obj.pos.y;

    obj.vel.x = obj.pos.x - obj.oldPos.x;
    obj.vel.y = obj.pos.y - obj.oldPos.y;
    // Log "1." here        

    resolveScreenCollision(obj);

    obj.pos.x += obj.FRICTION * (dt / lDT) * obj.vel.x + gravityX * (dt * dt);
    obj.pos.y += obj.FRICTION * (dt / lDT) * obj.vel.y + gravityY * (dt * dt);

    obj.oldPos.x = mTmp.x;
    obj.oldPos.y = mTmp.y;
    // Log "2." here
}

// Screen edge detection and resolver
public void resolveScreenCollision(Renderable obj) {
   final short xmax = (short) (mSV.mViewWidth - obj.width);
   final short ymax = (short) (mSV.mViewHeight - obj.height);
   final float x = obj.pos.x;
   final float y = obj.pos.y;

   // Only testing bottom of screen for now     
   if (y > ymax) {
    // ...
    } else if (y < 0.5f) {
        if(Math.abs(obj.vel.y) > 2.5f) {
            float imp = (obj.MASS * (obj.vel.y * obj.vel.y) / 2) * obj.RESTITUTION / obj.MASS;
            obj.vel.y += imp;
           // Log "bounce" here
        } else {
            obj.vel.y = obj.pos.y = obj.oldPos.y = mTmp.y = 0.0f;
        }
    }
}

Output while ball is resting on the floor and sudden impulse happens (see code for "log" comments)

1.  vel.y: -0.48258796
2.  pos.y: -0.42748278 /oldpos.y: 0.0 /dt: 0.016 /ldt: 0.017

1.  vel.y: -0.42748278
dalvikvm  GC_FOR_MALLOC freed 8536 objects / 585272 byte s in 74ms
2.  pos.y: -0.48258796 /oldpos.y: 0.0 /dt: 0.017 /ldt: 0.016

1.  vel.y: -0.48258796
2.  pos.y: -18.061148 /oldpos.y: 0.0 /dt: 0.104 /ldt: 0.017

1.  vel.y: -18.061148
bounce  imp: 124.35645
2.  pos.y: 13.805508 /oldpos.y: -18.061148 /dt: 0.015 /ldt: 0.104
最佳回答

you shouldn t use a timestep based on how much time occured from the previous calculation because that can cause problems such as this and errors in collision detection, if you don t have that yet. Instead for every update, you should set a "time chunk" or a max amount of time for each update. For example: say you want 30fps and the which is in nanotime about 33333333. so 33333333 = 1 timechunk. so then you could do a while loop

long difftime = System.nanoTime() - lastTime;
static long fpstn = 1000000000 / 30;
static int maxtimes = 10;// This is used to prevent what is commonly known as the spiral of death: the calcutaions are longer that the time you give them. in this case you have to increase the value of a base timechunk in your calculations
for (int i = 0; i < maxtimes; i++) {
    if (difftime >= fpstn) {
        world.updateVerlet(1);
    } else {
        world.updateVerlet((float)diffTime / (float)fpstn);
    }
    difftime -= fpstn;
    if (difftime <= 0)
        break;
}
问题回答

它很难确定,但看起来问题在时间步骤中是increase的,而是在时间步骤上用large。 您将Verlet的融合和放弃作为单独的过程,因此,如果气球从地板上的休息位置开始,会走很长的一段时期,会走到地板上,加快速度,然后才能反映在空气中。 保持时间小,你得起这个问题......很多。





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签