プロが教えるわが家の防犯対策術!

次のPythonで物理のシミュレーションするコードに、
1m(メートル)=10pixelの単位変換するプログラムを追加して修正したのですが、
コマンドプロンプトらしきものが少し立ち上がってすぐ落ちてしまします。
どこを修正すればちゃんと描画されますでしょうか?
おそらく目盛り線のところがPythonのGUIに適合していないのかと疑っております。

import tkinter
import math

def meter_to_pixel(meters):
return meters * 10

def move():
global x, y, vy, t, x1, y1

# ボールの新しい位置を計算
if 0 <= x and x <= WIDTH and 0 <= y and y <= HEIGHT:
x = x + meter_to_pixel(vx0 * dt)
v1 = vy
v2 = vy - g * dt
y = y + meter_to_pixel((v1 + v2) / 2.0 * dt)
vy = v2
t = t + dt
else:
x = x0
y = y0
vy = vy0
t = t0

# ボールの位置を更新
canvas.coords('ball', x-MARGIN, (HEIGHT-y)-MARGIN, x+MARGIN, (HEIGHT-y)+MARGIN)
canvas.coords('ball1', x1-MARGIN, (HEIGHT-y1)-MARGIN, x1+MARGIN, (HEIGHT-y1)+MARGIN)

# 目盛り線を描画
draw_scale_lines()

window.after(10, move) # 10ミリ秒ごとにmove関数を呼び出す

def draw_scale_lines():
# 目盛り線を描画
for i in range(1, WIDTH // (10 * scale_factor) + 1):
x_pos = i * 10 * scale_factor
canvas.create_line(x_pos, 0, x_pos, HEIGHT, fill='#d2d2d2')

for i in range(1, HEIGHT // (10 * scale_factor) + 1):
y_pos = i * 10 * scale_factor
canvas.create_line(0, y_pos, WIDTH, y_pos, fill='#d2d2d2')


# WIDTH, HEIGHT = 1000, 500
WIDTH, HEIGHT = 800, 600
MARGIN = 10

t0 = 0.0
dt = 0.1
g = 9.8

v0 = float(input('初速度(m/s)を入力してください: '))
degrees = float(input('角度(度)を入力してください: '))

theta = degrees * math.pi / 180
vx0 = v0 * math.cos(theta)
vy0 = v0 * math.sin(theta)
x0 = meter_to_pixel(10) # スケールファクターを適用
y0 = meter_to_pixel(2 * HEIGHT / 4) # スケールファクターを適用
x1 = meter_to_pixel(250) # スケールファクターを適用
y1 = meter_to_pixel(HEIGHT / 2) # スケールファクターを適用
x = x0
y = y0
vy = vy0
t = t0

# スケールファクターを設定
scale_factor = 100 / 10 # 現実世界の10メートル(m)に対して100ピクセル(pixel)

geo_str = str(WIDTH+MARGIN*2) + 'x' + str(HEIGHT+MARGIN*2)
window = tkinter.Tk()
window.geometry(geo_str)
window.title('moving')

canvas = tkinter.Canvas(window, width=WIDTH, height=HEIGHT, bg='white')
canvas.place(x=MARGIN, y=MARGIN)
canvas.create_oval(x-MARGIN, (HEIGHT-y)-MARGIN, x+MARGIN, (HEIGHT-y)+MARGIN, fill='red', outline='', tags='ball')
canvas.create_oval(x1-MARGIN, (HEIGHT-y1)-MARGIN, x1+MARGIN, (HEIGHT-y1)+MARGIN, fill='gray', outline='', tags='ball1')

move()
window.mainloop()

質問者からの補足コメント

  • 回答有難うございます。また、別の質問で書籍の件でマジレス有難うございます。
    Pythonのtkinterはたまたま自分のローカルPCで使いやすい環境にあるから使用しているだけです、
    計算物理の本格的なところができるようになるにはまだ遠いので、簡単なことから基本を押さえながらシミュレーションしていきたいとやっています。
    scale_factor = 100 // 10
    として実行しましたが、コマンドプロンプトが立ち上がるとすぐに画面が落ちてしまい描画されませんでした。他に修正すべきところがあるのでしょうか?

    No.1の回答に寄せられた補足コメントです。 補足日時:2023/06/03 14:00

A 回答 (2件)

# スケールファクターを設定


scale_factor = 100 / 10 # 現実世界の10メートル(m)に対して100ピクセル(pixel) <= この計算結果が float になるんで関数draw_scale_lines内のルーピング(range)内でfloatが発生し、エラーになる => 100 // 10 にすべき
この回答への補足あり
    • good
    • 1
この回答へのお礼

一応、動作しました。有難うございました。

https://www.ideone.com/M43tY6

しかし、実行すると画面の、大きくなった目盛り線だけが表示され、ボールが画面の範囲外になるのか、ボールが動いているようすがわかりません、さらに修正が必要なようです。また改めさせて頂きたいと思います。

お礼日時:2023/06/07 08:25

> 別の質問で書籍の件でマジレス有難うございます。



うん、「計算物理学入門」はマジで良い本です。
あんま日本でポピュラリティが無いみたいだけど、例えば岩波の同種書籍なんかより全然分かりやすくて面白いです(っつーか、岩波はネームヴァリューの割には編集者が全然仕事してないのが丸わかりで(笑)、「学者の言う通り、難解な本を出せばそれでイイ」って思ってるだろうクソな本ばっか、だ)。
しかも「計算物理学入門」は「入門」って言いながらある程度「大全」みたいになってるし、下手に日本で出版されている「アルゴリズム」系の本より全然いいですよ。
加えて「人気がない」お陰で古本が基本クッソ安い(笑)。
オススメ、です。

> Pythonのtkinterはたまたま自分のローカルPCで使いやすい環境にあるから使用しているだけです

いや、確固とした「Pythonを使う理由」があるならそれでいいです。
ただ、プログラミングスタイルが、言っちゃえば「古のプログラミングスタイル」だったし、プログラムが書けないワケじゃあないんで、単純にFortran経験者か、あるいは昔のNECのパソコンに載ってたN88 BASICの経験者なのかな、って邪推しただけ、です。

> 計算物理の本格的なところができるようになるにはまだ遠いので、簡単なことから基本を押さえながらシミュレーションしていきたいとやっています。

まぁでも、ぶっちゃけた事を言うと、コンピュータは元々「そのための」機械だし、フツーのプログラムを書くよか簡単なんで、割に早く(物理シミュレーション自体は)アレコレ出来るようにはなるんじゃないんですかね。

> scale_factor = 100 // 10
> として実行しましたが、コマンドプロンプトが立ち上がるとすぐに画面が落ちてしまい描画されませんでした。他に修正すべきところがあるのでしょうか?

これは不思議だね。僕のLinuxだと問題なく実行はされてます。貴方の想定通りの動きをしてるかどうかは知りませんが。
一応、使ってるOSがWindowsと仮定して、対処法は

https://oshiete.goo.ne.jp/qa/13484147.html

の方に載せておきました。
「Pythonにおける物理のシミュレーショ」の回答画像2
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!