2016-09-27 52 views
2

我試圖在android上模擬標槍彈跳。我計算標槍軌跡各點的切線斜率。標槍在每個標槍彈道點處模擬切線斜率

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)) 

:計算軌跡我使用拋射體運動方程

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

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

計算切線斜率標槍軌跡我推導這個方程關於x座標問題是,它可以在仰角<下正確工作而不是大約60度。 如果仰角較大,則不計算正確的斜率。

下面是代碼:

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); 
    } 
} 

我真不明白,爲什麼OT不正確更大的角度工作。請有任何想法嗎?

+0

什麼是應該第二個等式是? 'y'相對於't'的導數是'dy = g * t - v0 * Math.sin(弧度)'。產生的角度是tan(dy)'。 –

+0

@NicoSchertler嗨Nico,第二個方程應該計算y座標相對於時間t。我需要的是計算第三方程的代數方程,它表示我的標槍相對於座標x的軌跡。順便說一句,我不知道爲什麼我可以直接使用'javelin_angle = Math.toDegrees(Math.tan(radians) - (g * x)/(Math.pow(v0,2)* Math)來使用DerivativeStructure。 pow(Math.cos(radians),2)));'但情況是一樣的,並且只有當仰角低於65度時才能正常工作 – naco

回答

0

首先,您對y(x)的解決方案似乎會降低一些變量(例如x0)。以下是完整的解決方案:

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

相對於該衍生物x是:

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

你的溶液看起來不同之處在於它的y軸被反轉非常相似,並且它忽略了初始位置。

對應於該導數的角度是其arctangens:

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

我假定,有爲什麼你交換y軸的一個原因。所以你可以在這個公式中再做一次。

爲什麼你的配方工作對於小角度的原因是arctangens靠近身份對於小角度(標識爲紅色,藍色arctangens):

Arctangens

+0

謝謝!它現在完美。我還需要更改'mat.postRotate(-alpha);'以正值'mat.postRotate(alpha);'。謝謝你的解釋。 – naco