2016-05-29 12 views
0

Ich versuche, ein Auftriebskraftverhalten auf einem 2D-Objekt einer Android-Anwendung zu simulieren, es gibt keine Reibung beteiligt. Etwas funktioniert nicht richtig: Die Höhe des "Bounce" ändert sich unregelmäßig, ich denke, der Fehler sollte in der Aktualisierung der Geschwindigkeit liegen, aber ich bin mir nicht sicher.Booyant Force Simulation

Kann jemand den Fehler in meinem Code sehen?

public class MainActivity extends Activity { 

    Semaphore moveSemaphore = new Semaphore(1); 
    static WindowManager.LayoutParams params; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     params = new WindowManager.LayoutParams(80, 80, 
       WindowManager.LayoutParams.TYPE_APPLICATION, 
       WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, 
       PixelFormat.TRANSPARENT); 

     final BallView ball = new BallView(this); 
     addContentView(ball, params); 
     ball.setX(100); 
     ball.setY(50); 

     final Thread move = new Thread(new Runnable(){ 
      double speed = 0; 
      double G = 9; 
      double fullBuoyancy = -G * 10; 
      double prevtime = System.currentTimeMillis(); 
      double elapsed; 

      double fluidstart = 300; 
      double objectHeight = 100; 
      double currPosy = 50; 
      double p; 

      @Override 
      public void run() { 

       while(true){ 

        try { 
         moveSemaphore.acquire(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 

        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          double currDepth = 0; 
          long currtime = System.currentTimeMillis(); 
          elapsed = (currtime - prevtime) * 0.01; 
          prevtime = currtime; 
          currPosy = ball.getY(); 

          // COMPUTE HOW MUCH OF THE BALL IS INSIDE OF THE FLUID 
          if (currPosy > (fluidstart + objectHeight/2)){ 
           currDepth = objectHeight; 
          } else if (currPosy > (fluidstart - objectHeight/2)) { 
           currDepth = currPosy - fluidstart; 
          } 


          p = currDepth/objectHeight; // PERCENTAGE OF THE FULL BUOYANT FORCE TO BE APPLIED 
          speed = speed + (G + fullBuoyancy * p) * elapsed; 

          currPosy += speed * elapsed; 
          ball.setY((float)currPosy); 

          moveSemaphore.release(); 
         } 
        }); 
       } 
      } 
     }); 

     move.start(); 
    } 
} 

Antwort

0

Die if-Anweisungslogik ist falsch.

double emerge = fluidstart - (currPosy - (objectHeight/2)); 
if (emerge <= 0) { // complete submersion 
    currDepth = objectHeight; 
} else { 
    currDepth = objectHeight - emerge; 
} 
+0

Hallo, vielen Dank für Ihre Antwort! es war tatsächlich ein Problem der if-Anweisung, aber die Lösung ist ein wenig anders als Ihre, da die y-Achse in diesem Fall nach unten zeigt. Der Fall currDepth = 0 ist abgedeckt, da sein Wert zu Beginn der Schleife auf diesen Wert initialisiert wird. – u09

+0

@ u09 bearbeitet. Entschuldigung, ich habe diesen Teil vermisst - ich dachte, du hättest ihn draussen wie die anderen Variablen erklärt :) –

0

Das Problem in der if-Anweisung war, ist dies die richtige Lösung:

if (currPosy > (fluidstart + objectHeight/2)){//complete submersion 
    currDepth = objectHeight; 
} else if (currPosy > (fluidstart - objectHeight/2)) {//partial submersion 
    currDepth = (currPosy + objectHeight/2) - fluidstart; 
}