2016-09-27 5 views
2

Ich versuche zu simulieren Speerwurf auf Android. Ich berechne Steigung der Tangente in jedem Punkt der Speerbahn. Um Trajektorie zu berechnen Koordinaten Ich verwende Bewegung Projectile GleichungenSpeerwurf Simulation Berechnung der Steigung der Tangente an jedem Speer Trajektoriepunkt

x = (int) (x0 + v0 * t * Math.cos(radians)); //for coordinate x 

und

y = (int) (y0 - v0 * t * Math.sin(radians) + 0.5 * g * t * t); 

zur Steigung der Tangentenlinie berechnen zu Speerwurf Trajektorie I diese Gleichung derivatisiert mit Bezug auf x:

y = Math.tan(radians) * x - g/(2 * Math.pow(v0, 2) * Math.pow(Math.cos(radians), 2)) * x^2 
dy = Math.tan(radians) - (g * x)/(Math.pow(v0, 2) * Math.pow(Math.cos(radians), 2)) 

Problem ist, dass es korrekt funktioniert mit Höhenwinkel < als etwa 60 Grad. Wenn der Elevationswinkel größer ist, berechnet er nicht die korrekte Steigung. Hier

ist der Code:

public class ThrowJavelin extends ImageView { 
    private Context mContext; 
    int x0 = -1; 
    int y0 = -1; 
    int x = x0; 
    int y = y0; 
    private Handler h; 
    private final int FRAME_RATE = 5; 
    private double t = 0; 
    private float g = 9.81f; 
    //initial velocity 
    private int v0; 
    //elevation angle in radians 
    private double radians; 
    //javelin current angle in degrees 
    private double javelin_angle; 



    public ThrowJavelin(Context context, AttributeSet attr) { super(context, attr); } 
    public ThrowJavelin(Context context, AttributeSet attrs, int defStyleAttr){ super(context, attrs, defStyleAttr); } 

    public ThrowJavelin(Context context, Bundle args) { 
     super(context); 
     mContext = context; 
     h = new Handler(); 
     //input values 
     v0 = args.getInt("velocity"); 
     radians = args.getDouble("radians"); 
    } 

    private Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      invalidate(); 
     } 
    }; 

    protected void onDraw(Canvas c) { 

     Bitmap javelin = BitmapFactory.decodeResource(getResources(), R.drawable.jav); 
     DerivativeStructure alpha = null; 
     if (x < 0 && y < 0) { 
      x0 = 0; 
      y0 = c.getHeight() - 200; 
      x = x0; 
      y = y0; 
      javelin = rotateBitmap(javelin, (float) Math.toDegrees(radians)); 
     } else if (y > y0) { //reset to beginning 
      x = x0; 
      y = y0; 
      t = 0; 
      javelin = rotateBitmap(javelin, (float) Math.toDegrees(radians)); 
     } else { 
      //calculate current coordinates (depends on t) 
      x = (int) (x0 + v0 * t * Math.cos(radians)); 
      y = (int) (y0 - v0 * t * Math.sin(radians) + 0.5 * g * t * t); 

      if (x == 0) { 
       javelin_angle = Math.toDegrees(radians); 
      } else { 
       // dy of 3rd equation 
       javelin_angle = Math.toDegrees(Math.tan(radians) - (g * x)/(Math.pow(v0, 2) * Math.pow(Math.cos(radians), 2))); 
      } 
      javelin = rotateBitmap(javelin, javelin_angle); 
      t += 0.3; 
     } 
     c.drawBitmap(javelin, x, y, null); 

     h.postDelayed(r, FRAME_RATE); 

    } 



    public Bitmap rotateBitmap(Bitmap image, double angle){ 
     float alpha = (float) angle; 

     Matrix mat = new Matrix(); 
     System.out.println(-alpha); 
     mat.postRotate(-alpha); 
     return Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), mat, true); 
    } 
} 

Ich verstehe wirklich nicht, warum ot nicht richtig für größere Winkel funktioniert. Irgendwelche Ideen bitte?

+0

Was diese zweite Gleichung soll Sein? Die Ableitung von "y" in Bezug auf "t" ist "dy = g * t - v0 * Math.sin (Bogenmaß)". Der resultierende Winkel ist "tan (dy)". –

+0

@NicoSchertler Hallo Nico, die zweite Gleichung soll die y-Koordinate in Bezug auf die Zeit t berechnen. Was ich brauche, ist den Derevativ der 3. Gleichung zu berechnen, die die Flugbahn meines Speers in Bezug auf die Koordinate x darstellt. Übrigens weiß ich nicht, warum ich DerivativeStructure verwende, wenn ich direkt 'javelin_angle = Math.toDegrees (Math.tan (Bogenmaß) - (g * x)/(Math.pow (v0, 2) * Math) verwenden kann. pow (Math.cos (radians), 2))); 'Aber die Situation ist die gleiche und und alles funktioniert nur dann korrekt, wenn der Elevationswinkel niedriger als 65 Grad ist – naco

Antwort

0

Erstens scheint Ihre Lösung für y(x) ein paar Variablen (z. B. x0) fallen. Hier ist die vollständige Lösung:

y(x) = y0 + (0.5 * g * (x - x0)^2)/(v0^2 * cos(radians)^2) - (x - x0) * tan(radians) 

Das Derivat mit Bezug auf x ist:

dy/dx = (g * (x - x0))/(v0^2 * cos^2(radians)) - tan(radians) 

Ihre Lösung sieht sehr ähnlich, außer dass seine y-Achse invertiert und es fehlt die Anfangspositionen.

Der Winkel, der zu diesem Derivat entspricht, ist sein arctangens:

double c = Math.cos(radians); 
javelin_angle = Math.toDegrees(Math.atan((g * (x - x0)/(v0 * v0 * c * c) - Math.tan(radians))); 

Ich gehe davon aus, es gab einen Grund, warum Sie die y-Achse vertauscht. Sie können das in dieser Formel wieder tun.

Der Grund, warum Ihre Formel für kleine Winkel gearbeitet ist, dass die arctangens der Identität für kleine Winkel nahe ist (Identität in rot, arctangens in blau):

Arctangens

+0

Danke! Es funktioniert jetzt perfekt. Ich musste auch "mat.postRotate (-alpha)" ändern. zum positiven Wert "mat.postRotate (alpha);". Danke für Ihre Erklärung. – naco

Verwandte Themen