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));//計算した到達距離
}