【问题标题】:Javelin throw simulation calculation of slope of tangent line at every javelin trajectory point标枪各弹道点切线斜率的标枪投掷模拟计算
【发布时间】:2016-09-27 11:39:27
【问题描述】:

我正在尝试在 android 上模拟 标枪投掷。我计算了标枪轨迹每个点的切线斜率。为了计算轨迹坐标,我使用了 Projectile 运动方程

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 的方程:

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

问题是,它在仰角 如果仰角较大,则无法计算正确的坡度。

代码如下:

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 对于更大的角度不能正常工作。请问有什么想法吗?

【问题讨论】:

  • 第二个方程应该是什么? yt 的导数是 dy = g * t - v0 * Math.sin(radians)。结果角度为tan(dy)
  • @NicoSchertler 嗨 Nico,第二个方程应该计算 y 相对于时间 t 的坐标。我需要的是计算第三个方程的导数,它代表我的标枪相对于坐标 x 的轨迹。顺便说一句,我不知道为什么我可以直接使用 DerivativeStructure javelin_angle = Math.toDegrees(Math.tan(radians) - (g * x) / (Math.pow(v0, 2) * Math.pow(Math.cos(radians), 2))); 但情况是一样的,只有在仰角低于 65 度时才能正常工作

标签: java android math


【解决方案1】:

首先,您对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 轴是倒置的并且它错过了初始位置。

对应于这个导数的角度是它的反正切:

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

我认为,您交换 y 轴是有原因的。所以你可以在这个公式中再次这样做。

您的公式适用于小角度的原因是反正切值接近小角度的恒等式(红色恒等式,蓝色表示反正切):

【讨论】:

  • 谢谢!它现在完美运行。我还需要更改 `mat.postRotate(-alpha);'为正值'mat.postRotate(alpha);'。谢谢你的解释。
猜你喜欢
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多