自由落下

 大気中の自由落下で、レイノルズ数による、大気の抵抗が速度に比例する場合と、乱流による速度の二乗に比例する抵抗に分けられるようですが、速度に比例する抵抗は、よほどゆっくりとした速度の場合で、大気中での落下は、殆どが速度の二乗に比例する抵抗となるようです。
 速度に比例する場合の抵抗は、ウィキペディアの自由落下を参照してください。
次の計算式は、空気抵抗が速度の二乗に比例する場合の計算式です。

 C値は、形状によって変化するので、一般的には実験によって求められます。

風洞によるD:抗力の測定か、自由落下による落下速度、或いは一定距離の落下時間を測定して求める事が多いようです。


 

 上図は、自由落下計算プログラムの実行画面です。
空気抗力係数0.4は、人が両手両足を広げて大の字になって落下するときの値です。
車は、0.24~0.3程度、落下傘は1前後のようです。
 落下傘の面積は30~40平方メートルですが、地表に降り立つときは、3メートル以上の高さから飛び降りたときの速度になるので、受け身を取らないとケガの恐れがあります。

(参考) パラグライダーは、滑空して揚力を発生させるので、ほぼ垂直に近く落下する落下傘より、落下速度は大幅に小さくなり、方向や速度も落下傘よりを自由にかえられます。
風の影響を大きく受けるのは、両者とも同じです。

プログラム

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    rhoEdit: TLabeledEdit;
    sumEdit: TLabeledEdit;
    KcalcBtn: TBitBtn;
    kEdit: TLabeledEdit;
    CdEdit: TLabeledEdit;
    Memo1: TMemo;
    GroupBox2: TGroupBox;
    mEdit: TLabeledEdit;
    tEdit: TLabeledEdit;
    gEdit: TLabeledEdit;
    vhBtn: TBitBtn;
    GroupBox3: TGroupBox;
    m1Edit: TLabeledEdit;
    h1Edit: TLabeledEdit;
    g1Edit: TLabeledEdit;
    tvBtn: TBitBtn;
    GroupBox4: TGroupBox;
    g2Edit: TLabeledEdit;
    t2Edit: TLabeledEdit;
    vh2Btn: TBitBtn;
    h2Edit: TLabeledEdit;
    tv2btn: TBitBtn;
    GroupBox5: TGroupBox;
    g3Edit: TLabeledEdit;
    t3Edit: TLabeledEdit;
    k3Edit: TLabeledEdit;
    m3Edit: TLabeledEdit;
    vh3Btn: TBitBtn;
    procedure KcalcBtnClick(Sender: TObject);
    procedure vhBtnClick(Sender: TObject);
    procedure tvBtnClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure vh2BtnClick(Sender: TObject);
    procedure tv2btnClick(Sender: TObject);
    procedure vh3BtnClick(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses system.Math;

// 空気の抵抗が無い場合で距離から時間と速度計算
procedure TForm1.tv2btnClick(Sender: TObject);
var
  t   : double;   // 落下時間      sec
  g   : double;   // 重力加速度    m/sec^2
  v   : double;   // 落下速度      m/s
  h   : double;   // 高さ          m
  ch  : integer;
begin
  memo1.Clear;
  val(h2Edit.Text, h, ch);
  if ch <> 0 then begin
    Memo1.Text := 'h:高さに間違いがあります。';
    exit;
  end;
  if h <= 0 then begin
    Memo1.Text := 'h:高さの値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(g2Edit.Text, g, ch);
  if ch <> 0 then begin
    Memo1.Text := 'g:加速度に間違いがあります。';
    exit;
  end;
  if g <= 0 then begin
    Memo1.Text := 'g:加速度の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  t := sqrt(2 * h / g);
  v := g * t;
  memo1.Lines.Append('落下時間');
  memo1.Lines.Append(' t = ' + floatTostr(t) + ' sec');
  memo1.Lines.Append('落下速度');
  memo1.Lines.Append(' v = ' + floatTostr(v) + ' m/s');
end;

// 空気の抵抗が速度の2乗に比例するものとして距離から時間と速度計算
procedure TForm1.tvBtnClick(Sender: TObject);
var
  k   : double;   // 空気抵抗係数  kg/m
  m   : double;   // 質量          kg
  t   : double;   // 落下時間      sec
  g   : double;   // 重力加速度    m/sec^2
  v   : double;   // 落下速度      m/s
  h   : double;   // 高さ          m
  ch  : integer;
begin
  memo1.Clear;
  val(m1Edit.Text, m, ch);
  if ch <> 0 then begin
    Memo1.Text := 'm:質量に間違いがあります。';
    exit;
  end;
  if m <= 0 then begin
    Memo1.Text := 'm:質量の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(h1Edit.Text, h, ch);
  if ch <> 0 then begin
    Memo1.Text := 'h:高さに間違いがあります。';
    exit;
  end;
  if h <= 0 then begin
    Memo1.Text := 'h:高さの値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(kEdit.Text, k, ch);
  if ch <> 0 then begin
    Memo1.Text := 'k:空気抵抗係数に間違いがあります。';
    exit;
  end;
  if k <= 0 then begin
    Memo1.Text := 'k:空気抵抗係数の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(g1Edit.Text, g, ch);
  if ch <> 0 then begin
    Memo1.Text := 'g:加速度に間違いがあります。';
    exit;
  end;
  if g <= 0 then begin
    Memo1.Text := 'g:加速度の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  t := sqrt(m / (g * k)) * arccosh(exp(h * k / m));
  v := sqrt(m * g / k) * tanh(t / sqrt(m / (g * k)));
  memo1.Lines.Append('落下時間');
  memo1.Lines.Append(' t = ' + floatTostr(t) + ' sec');
  memo1.Lines.Append('落下速度');
  memo1.Lines.Append(' v = ' + floatTostr(v) + ' m/s');
end;

// 速度と空気抵抗が比例するものとしてt秒後の速度距離計算
// k:空気抵抗係数単位無し
procedure TForm1.vh3BtnClick(Sender: TObject);
var
  k   : double;   // 空気抵抗係数
  m   : double;   // 質量          kg
  t   : double;   // 落下時間      sec
  v   : double;   // 落下速度      m/s
  h   : double;   // 高さ          m
  g   : double;   // 重力加速度    m/sec^2
  ch  : integer;
begin
  memo1.Clear;
  val(g3Edit.Text, g, ch);
  if ch <> 0 then begin
    Memo1.Text := 'g:加速度に間違いがあります。';
    exit;
  end;
  if g <= 0 then begin
    Memo1.Text := 'g:加速度の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(t3Edit.Text, t, ch);
  if ch <> 0 then begin
    Memo1.Text := 't:時間に間違いがあります。';
    exit;
  end;
  if t <= 0 then begin
    Memo1.Text := 't:時間の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(k3Edit.Text, k, ch);
  if ch <> 0 then begin
    Memo1.Text := 'k:空気抵抗係数に間違いがあります。';
    exit;
  end;
  if k <= 0 then begin
    Memo1.Text := 'k:空気抵抗係数の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(m3Edit.Text, m, ch);
  if ch <> 0 then begin
    Memo1.Text := 'm:質量に間違いがあります。';
    exit;
  end;
  if m <= 0 then begin
    Memo1.Text := 'm:質量の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  v :=  m * g / k - m * g / k * exp(-k * t / m);
  h :=  m / k * (m / k * g * (exp(-k * t / m) - 1) + g * t);
  memo1.Lines.Append('落下距離');
  memo1.Lines.Append(' h = ' + floatTostr(h) + ' m');
  memo1.Lines.Append('落下速度');
  memo1.Lines.Append(' v = ' + floatTostr(v) + ' m/s');
end;

// 空気抵抗が無いものとして落下時間から速度と距離計算
procedure TForm1.vh2BtnClick(Sender: TObject);
var
  t   : double;   // 落下時間      sec
  v   : double;   // 落下速度      m/s
  h   : double;   // 高さ          m
  g   : double;   // 重力加速度    m/sec^2
  ch  : integer;
begin
  memo1.Clear;
  val(t2Edit.Text, t, ch);
  if ch <> 0 then begin
    Memo1.Text := 't:時間に間違いがあります。';
    exit;
  end;
  if t <= 0 then begin
    Memo1.Text := 't:時間の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(g2Edit.Text, g, ch);
  if ch <> 0 then begin
    Memo1.Text := 'g:加速度に間違いがあります。';
    exit;
  end;
  if g <= 0 then begin
    Memo1.Text := 'g:加速度の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  v := g * t;
  h := g * t * t / 2;
  memo1.Lines.Append('落下距離');
  memo1.Lines.Append(' h = ' + floatTostr(h) + ' m');
  memo1.Lines.Append('落下速度');
  memo1.Lines.Append(' v = ' + floatTostr(v) + ' m/s');
end;

// 空気抵抗が速度の2乗に比例するものとして時間から速度と距離計算
procedure TForm1.vhBtnClick(Sender: TObject);
var
  k   : double;   // 空気抵抗係数  kg/m
  m   : double;   // 質量          kg
  t   : double;   // 落下時間      sec
  g   : double;   // 重力加速度    m/sec^2
  v   : double;   // 落下速度      m/s
  h   : double;   // 高さ          m
  ch  : integer;
begin
  Memo1.Clear;
  val(kEdit.Text, k, ch);
  if ch <> 0 then begin
    Memo1.Text := 'k:空気抵抗係数に間違いがあります。';
    exit;
  end;
  if k <= 0 then begin
    Memo1.Text := 'k:空気抵抗係数の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(mEdit.Text, m, ch);
  if ch <> 0 then begin
    Memo1.Text := 'm:質量に間違いがあります。';
    exit;
  end;
  if m <= 0 then begin
    Memo1.Text := 'm:質量の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(tEdit.Text, t, ch);
  if ch <> 0 then begin
    Memo1.Text := 't:時間に間違いがあります。';
    exit;
  end;
  if t <= 0 then begin
    Memo1.Text := 't:時間の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  val(gEdit.Text, g, ch);
  if ch <> 0 then begin
    Memo1.Text := 'g:加速度に間違いがあります。';
    exit;
  end;
  if g <= 0 then begin
    Memo1.Text := 'g:加速度の値は0(ゼロ)より大きくしてください。';
    exit;
  end;
  h := m / k * ln(cosh(t / sqrt(m / (g * k))));
  v := sqrt(m * g / k) * tanh(t / sqrt(m / (g * k)));
  memo1.Lines.Append('落下距離');
  memo1.Lines.Append(' h = ' + floatTostr(h) + ' m');
  memo1.Lines.Append('落下速度');
  memo1.Lines.Append(' v = ' + floatTostr(v) + ' m/s');
end;

// 空気抗力係数から空気抵抗計算kg/m計算
procedure TForm1.KcalcBtnClick(Sender: TObject);
var
  k   : double;   // 空気抵抗係数  kg/m
  Cd  : double;   // 空気抗力係数
  r   : double;   // 空気密度   kg/m^3
  S   : double;   // 代表面積   m^2
  ch  : integer;
begin
  val(CdEdit.Text, Cd, ch);
  if ch <> 0 then begin
    Memo1.Text := 'Cd:空気抗力係数に間違いがあります。';
    exit;
  end;
  val(rhoEdit.Text, r, ch);
  if ch <> 0 then begin
    Memo1.Text := 'ρ:空気密度に間違いがあります。';
    exit;
  end;
  val(sumEdit.Text, S, ch);
  if ch <> 0 then begin
    Memo1.Text := 'S:代表面積に間違いがあります。';
    exit;
  end;
  k := Cd * r * s / 2;
  kEdit.Text := floatTostr(k);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  memo1.Text := '自由落下計算';
end;

end.

  download free_fall.zip

各種プログラム計算例に戻る