情報科学基礎 Information Literacy 2019

プログラミング環境 Processing を用いた物理学の計算

第11回 対面授業課題


注意

情報教育システムにはv3.3.5のProcessingが既にインストールされてい る。この実習ではこれを利用して頂く。

もし自宅のPC等で使用したい場合は、 オリジナルサイトからダ ウンロードして使う事が可能である。但し、オリジナルサイトでは最新 のv3.5.3がある。バージョンが異なると動作や使い方が変わることがあ るので、注意が必要である。皆さんが各自でより進んだ内容を勉強する 事は大変よいことであるが、試験、又はレポートで使用するバージョン は公平性を保つため、情報教育システムと同じバージョンとする。


課題1(描画1)

スタートボタンから「Devel」→「processing」を選択して Processing を起動する。

次に以下のプログラムを入力して実行してみよ。 コピー&ペーストは使用しないこと。


size(800,600)

for i in range(350):
    print("X="+str(i*2)+" Y="+str(i))
    point(i*2,i)

      
size 文で、描画する範囲を横800ピクセル、縦600ピクセルに指定している。

i を0から349まで、1つづ増やしながら、 X座標はiの2倍、Y座標はiの位置に、点を描画している。 X,Yの値は数値でも出力している。

点が小さくて見にくい場合は、point の代わりに、ellipse を使うと見やすくなる。

    ellipse(i*2, i, 1, 1)

ellipse は楕円を描画する関数である。半径の小さな楕円を描く事で、大きな点を描画している。

以下の事をやってみよ。

尚、Processingで使用できる関数等の説明が

にある。意味が分からないものはこれで調べて見よ。尚、オリジナルサ イトや検索サイトなどで調べた場合は、異なるバージョンの説明が表示 されることがあるので、注意せよ。


課題2(描画2)

以下のプログラムを入力して実行してみよ。コピー&ペーストは使用しないこと。


def setup():
    size(600,600)
    print("width="+str(width)+" height="+str(height))
    frameRate(30)
    line(sx(-100),sy(0),sx(+100),sy(0))
    line(sx(0),sy(-100),sx(0),sy(100))

x1=-100.0
y1=-100.0
x2=+100.0
y2=+100.0

def sx(x):
    global x1
    global x2
    return width*(x-x1)/(x2-x1)

def sy(y):
    global y1
    global y2
    return height*(y2-y)/(y2-y1)

x=0.0

def draw():
    global x

    y=0.01*x*x

    print("X="+str(x)+" Y="+str(y))
    point(sx(x),sy(y)) # elipse(sx(x),sy(y),1,1)
    x=x+1.0

    if x>100.0:
        noLoop()

      
13~17行は、座標変換のお膳立てをしている。 size 文で宣言された600×600ピクセルのスクリーンは、いわばXが1~600、Yが1~600の 座標を持っていると言える。但し、Yは下が大きい事に留意せよ。 これだと我々が自由に座標系を使えない。そこで、計算で使用する座標系からスクリーンに表示する座標系への 変換を考える。このプログラムでは計算で使用するXは、-100.0から+100.0まで、 Yも同じ範囲とし、Y軸は上が大きくなるように方向を逆転させる、一次変換を行う関数を定義している。

この関数はX,Y毎に1つづつ定義されている。 計算に使用する座標系は9~10行目で定義されている。 変換に必要なスクリーンのピクセル数は、size 文の実行後に、自動的に、width, height という変数に代入されている。

この関数は、下から4行目の point 関数で使用されている。 この様にすると、point関数が計算座標系のX、Yを引数に持っているかのごとく使える。

プログラムでは、2次関数を計算、描画している。

Xを0から1づつ増やし、100を超えたらループを終了している。 Xの初期値、終了条件、増分、関数形等を変更して、色々試してみよ。

setup関数はプログラムの最初に1度だけ実行される。

draw関数は、何もしなければ、自動的に無限回、実行される。 繰り返し計算し、その結果を描画する場合には、draw関数の中に、1回分の描画するプログラムを書けば、 それを繰り返してくれる。但し、パラメータの更新や、終了条件の判断は自分で書く必要がある。

関数形を変えて、異なるグラフを描け。

初期値、終わり値を変えてみよ。

スクリーンの大きさを変えてみよ。また、計算に使う座標系も変えてみよ。

draw関数はsetup関数の中でframeRate関数で設定された頻度で繰り返される。 このプログラムでは3回/秒としてある。この数値を変えてみよ。


課題3(放物運動)

以下のプログラムを入力して実行してみよ。 これ以降、コピー&ペーストを使用してもよいが、 プログラムの中身をしっかりと 読んで、理解する事。


def setup():
    size(600, 600)
    #frameRate(3)
    line(sx(-1000),sy(0),sx(+1000),sy(0))
    line(sx(0),sy(-1000),sx(0),sy(+1000))

x1=-1.0
y1=-100.0
x2=+10.0
y2=+10.0

def sx(x):
    global x1
    global x2
    return width*(x-x1)/(x2-x1)

def sy(y):
    global y1
    global y2
    return height*(y2-y)/(y2-y1)

m=1   #weight
x0=0.0  #initial position of x
y0=0.0  #initial position of y
vx0=10.0 #initial velocity of x
vy0=10.0 #initial velocity of y
dt=0.0050

x=x0
y=y0
vx=vx0
vy=vy0
t=0.0
i=0
g=-9.8

def draw():
    strokeWeight(3)
    global g
    global x
    global y
    global vx
    global vy
    global t
    global i

    #    point(sx(t),sy(vx))
    #    point(sx(t),sy(vy))
    #    point(sx(t),sy(x))
    point(sx(t),sy(y))
    #    point(sx(x),sy(y))
    print("vx="+str(vx)+" vy="+str(vy)+" x="+str(x)+" y="+str(y)+" t="+str(t))

    t=t+dt
    vx=vx
    vy=vy+g*dt  
    x=x+vx*dt
    y=y+vy*dt
	  
    i=i+1
	  
    if i>2000:
        noLoop()

      
このプログラムは、質点の放物運動を数値計算で解いている。

物理学で言う、数値計算で問題が「解けた」とは、

をいう。

重力加速度は、-9.8m/s/s(下方へなので符号は負)とし、 質点を座標(0m,0m)から初速度(10m/s、10m/s)で飛ばした時の運動を追跡している。

時間の刻みは0.01秒とし、ある時刻から次の時刻の速度と座標は以下のように求めている。

Vx ← Vx
Vy ← Vy + g・Δt

X ← X + Vx・Δt
Y ← Y + Vy・Δt

これらの式は、速度と加速度の定義から分かると思う。

Vx(t) = ( X(t+Δt) - X(t) ) / Δt (Δt→0)
Ax(t) = ( Vx(t+Δt) - Vx(t) ) / Δt (Δt→0)

この様に1次の極限での近似を用いて数値積分する方法を、オイラー法という。

プログラムの最後の方に、X軸とY軸に何を描画するかが、何行かに渡り書いてあり、 1つを除きコメントアウトされている。これらをそれぞれ描画し、計算の結果を確認せよ。 初速度を変えて試してみよ。

このように、物理現象をシミュレーションする場合には、物理法則に関わる部分には一切修正を加えず、 初期値等の条件を変更する事で、様々な物理現象を再現できる。

Δtは0.01秒で計算したが、これを0.02秒に粗くしてみよ。 グラフでは分からない程度の差しかでないので、出力された数値を比較して、計算誤差が変化する事を確認せよ。

#(シャープ)は、コメント機能である。この記号から行末までは、コメントとなり、プログラムの実行に何の影響も与えない。 また、''' コメント ''' という構造を使用すれば、複数行にまたがったコメントも作成できる。


課題4(地球の公転)

以下のプログラムを入力して実行してみよ。 これ以降、コピー&ペーストを使用してもよいが、 プログラムの中身をしっかりと 読んで、理解する事。


def setup():
    size(600, 600)
    frameRate(1000)
    colorMode(RGB)
    background(0,0,0)
    stroke(255,0,0)
    fill(255,0,0)
    ellipse(sx(0),sy(0),5,5)
    stroke(0,255,0)
    fill(0,255,0)

x1=-1.6e11
y1=-1.6e11 
x2=+1.6e11
y2=+1.6e11

def sx(x):
    global x1
    global x2
    return width*(x-x1)/(x2-x1)

def sy(y):
    global y1
    global y2
    return height*(y2-y)/(y2-y1)

t=0.0
dt=80000.0
x=1.496e11
y=0.0
vx=0.0
vy=2.979e4
G=6.67384e-11
Ms=1.989e30

i=0

def draw():
    global x
    global y
    global t
    global i
    global vx
    global vy
    global G
    global Ms

    print("vx="+str(vx)+" vy="+str(vy)+" x="+str(x)+" y="+str(y)+" t="+str(t))
    point(sx(x),sy(y))
    t=t+dt
    r3=(x**2+y**2)**1.5
    vx=vx-G*Ms*dt*x/r3
    vy=vy-G*Ms*dt*y/r3
    x=x+vx*dt
    y=y+vy*dt

    i=i+1

    if i>10000:
        noLoop()

      
このプログラムは、太陽の周りを回る地球の動きをシミュレーションしている。

最初の方で、色を指定している。

初期条件として、太陽と地球の距離、地球の速度は、現実的な値を入れてあるが、 この場合、綺麗に円軌道が再現できる。

初速度を変えると楕円軌道になる筈なので、やってみよ。

初速(vy=2.979e4)を約半分(1.5e4)にすると楕円軌道がだんだんずれていってしまう。 これは計算誤差が蓄積するからである。dtの値を小さくすると計算誤差が減り、 より正しい結果を得られる事を確かめよ。

dtの値を小さくした場合は、frameRate で大きな値を指定すると速く計算する。 指定しなかった時の値は60である。


これで第11回 対面授業は終わりです。お疲れ様でした。第12回の E-leaning は第13回対面授業までに終わらせてください。