dx=vx*dt ;速度の定義より
質量 * 加速度 = 力 :ニュートンの法則これが、力と質量、加速度の間の関係式になります。質量 m の物体に力Fを加えると、加速度aは次のようになります。
dy = vy * dt, dx = vx * dtとなります。手から離れた直後のボールのx,y方向の速度を vx0 と vy0 とします。これを初速度といいます。
vx0=v*cos(ang)、vy0=v*sin(ang)となります。cos(ang)、sin(ang)は三角関数で、vのx成分とy成分を計算します。
vy(t)=vy0 - g * dtとなります。vy0/g 秒後にはy方向の速度は0になり、以後落下をはじめます。
t=vy0/g=v・sin(ang)/gとなります。また、最高点の高さは、y方向の速度が0になるまでの、時刻-速度 グラフの面積ですから、
x(t)=vx0 * tとなります。一方、y方向の速度は重力により刻々変化します。ごく短い時間 dt では、速度は一定と考えられますから、dtでの移動距離は
vy(t)*dt = (vy0-g*t)*dt = vy0*dt - g*t*dtとなります。実際の移動距離は、この短い時間dtでの移動距離の総和になります。下図より、この総和は矩形の面積 vy0*t から下の三角の面積 (1/2)*g*t*t を引いた値になります。したがって、
y(t)=vy0*t - (1/2)*g*t*tこれは、tに対する上に凸の2次曲線になります。水平方向の到達距離は、y(t) = 0 となる時刻です。これを解くと、
x = vx0*t = 2*vy0*vx0/g = 2*v*v*sin(ang)*cos(ang)/gが、水平方向の到達距離になります。これを ang の関数と考えると、angが45度のとき最大になります。
2sin(x)cos(y) = sin(x+y) + sin(x-y),が誘導できます。ここで、x=y とすると、
2*v*v/gとなります。
vx0=ve*(float)cos((3.14/180.0)*ang);となります。ここで、(3.14/180.0)*ang で角度をラジアン単位に直しています(180度がπラジアンです)。
vy0=ve*(float)sin((3.14/180.0)*ang);
x = x + vx * dt;//位置変化 y = y + vy * dt; vy = vy - g * dt;//速度変化となります。ここで、dtは十分短くする必要があります。ここでの、計算は「dtの間はvx,vyは変化しない」、ことを前提としています。dtを大きくすると、この条件が成立しなくなるからです、
{ // 軌跡の計算 float ve,ang,vx0,vy0; float g,dt,t1,t,x,y,vx,vy; //速度設定、角度読み込み、初速度計算 ve=30.0; vx0=ve*(float)cos((3.14/180.0)*ang); vy0=ve*(float)sin((3.14/180.0)*ang); //重力加速度、刻み時間、落下時刻 g=9.8f; dt=0.01f; //初期設定 x=0;y=0; vx=vx0;vy=vy0; for( t=0.0;y>=0;t=t+dt){ x = x + vx * dt;//位置変化 y = y + vy * dt; vy = vy - g * dt;//速度変化 } }
v=sqrt(vx*vx+vy*vy); vx=vx - k*v*vx*dt vy=vy - g *dt - k*v*vy*dtとなります。
void Onthrow() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください double ve,vx0,vy0; double gv,dt,t1,t,x,y,vx,vy; double v; double m_ang,m_k; //描画の幅、高さ int xw=300,yw=200; int ox=10,oy=yw; int nx,ny; int prvx=ox,prvy=oy; Graphics g; g=getGraphics(); //地表を表示 g.drawLine(ox+xw,oy,ox,oy); //初速度設定、角度読み込み、空気抵抗設定 m_ang=Integer.parseInt(textAngle.getText()); m_k=(double)(Integer.parseInt(textFieldTeikou.getText()))/1000; ve=30.0;//初速度計算 vx0=ve*Math.cos((3.14/180.0)*m_ang); vy0=ve*Math.sin((3.14/180.0)*m_ang); //重力加速度、刻み時間、落下時刻 gv=9.8f; dt=0.005f; t1=2.0f*vy0/gv; x=0;y=0; vx=vx0;vy=vy0; double scale=(xw*gv)/(ve*ve);//描画倍率 v=0.0; int j=0; //シミュレーション開始 t:時刻 (x,y):位置 for( t=0.0;y>=0;t=t+dt){ j=j+1; v=Math.sqrt(vx*vx+vy*vy); x = x + vx * dt;//位置変化 y = y + vy * dt; vx=vx-m_k*v*vx*dt;//速度変化 vy=vy-gv*dt-m_k*v*vy*dt; //現在の位置を表示 (ox,oy)は原点の位置 nx=ox+(int)(x*scale); ny=(int)(oy-y*scale); if(j>=20){ g.drawArc(nx-1,ny-1,3,3,0,360); j=0; } g.drawLine(prvx,prvy,nx,ny);//軌跡描画 prvx=nx;prvy=ny; } labelDist.setText(Double.toString(x));//計算した到達距離 }