次のようにボールの位置(x,y)を物理の公式通りにして
Pythonでシミュレーションプログラムを書き、
canvas上にプロットした場合、
①10pixel =何m
10pixel/s=何 m/s
1 m= 何pixel
1 m/s= 何 pixel/s
でしょうか?
②v0 = float(input('初速度を入力してください'))のこの場合の初速度v0の単位は(m/s)でしょうかそれとも(km/s)でしょうか?
※時速30km=30km/h=8.3m/sは確かなので、この値は参考になると思います。
ポイントは
x = x + vx0 * dt
v1 = vy
v2 = vy - g * dt
y = y + (v1+ v2) / 2.0 * dt
vy = v2
WIDTH, HEIGHT = 800, 600
g = 9.8
v0 = float(input('初速度を入力してください'))
vx0 = v0 * math.cos(theta)
vy0 = v0 * math.sin(theta)
のところだと思います。
def move():
global x
global y
global vy
global t
global x1
global y1
if 0 <= x and x <= WIDTH and 0 <= y and y <= HEIGHT:
x = x + vx0 * dt
v1 = vy
v2 = vy - g * dt
y = y + (v1+ v2) / 2.0 * dt
vy = v2
t = t + dt
WIDTH, HEIGHT = 800, 600
MARGIN = 10
t0 = 0.0
dt = 0.1
g = 9.8
v0 = float(input('初速度を入力してください'))
degrees = float(input('角度を入力してください'))
theta = degrees * math.pi / 180
vx0 = v0 * math.cos(theta)
vy0 = v0 * math.sin(theta)
x0 = 10
y0 = 2 * HEIGHT / 4
x1 = 250
y1 = HEIGHT / 2
x = x0
y = y0
vy = vy0
t = t0
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
○メートルを使った座標とcanvas上の座標のどちらを使う場面なのか、きっちり区別するようにしましょう。
canvasに対して指定するのはcanvas上の座標です。
canvas.create_line(0, i * 10,800, i * 10, fill = '#000000' if i==30 else '#d2d2d2')
は canvas左上を(0,0)で右下が(正,正)となるpixcel座標で y= (i * 10) pixel の位置に線を引きます。
左下が(0,0)で右上が(正,正)となるメートル座標で y= (i * 10) メートルに引きたいのなら、メートル座標→canvas座標の変換が必要です。
800 も canvas座標のx=800pixelの意味で 800mではありません。
変換は、変換用関数を用意すると便利です。
例)
def xc(x): return 10 * x + 400
def yc(y): return -10 * y + 300
#(0m,( i * 10)m)から(800m, (i * 10)m)に線を引く
canvas.create_line(xc(0), yc(i * 10),xc(800), yc(i * 10), fill = '#000000' if i==30 else '#d2d2d2')
○ 入力とは、プログラム外からデータ等を受けとることです。
例) キーボード、マウス、ファイル、ネットワーク等
出力とは、プログラム外へデータ等を渡すことです。
例) 画面、ファイル、ネットワーク等
入出力と計算を分ける というのは、入出力は入出力だけ、計算は計算だけで動かせるようにして、互いの関係を必要最小限にするということです。
例えば
x0 = 10
y0 = 2 * HEIGHT / 4
x1 = 250
y1 = HEIGHT / 2
if 0 <= x and x <= WIDTH and 0 <= y and y <= HEIGHT
これらに出てくる 数値やWIDTH,HEIGHTはcanvasのpixelの値だと思われます。
ところが、これらの値がメートルを基準にした計算部分でそのまま使われています。
これは、計算が入出力に依存している状態です。
今回のプログラムなら
キーボードで必要なパラメータを入力(単位は度、m/s)
↓ラジアンに変換
計算
↓メートル座標をPixel座標に変換
画面出力
とすることで、入力と計算を分けることになります。
これができると
ウインドウにあるTextboxでパラメータを入力(単位は度、km/s)
↓ラジアンに変換
計算
↓メートル座標のまま
CSVファイルに出力
といったプログラムも、計算部分を変えることなく作ることができます。
クラス、モジュール、関数といったものを使って、プログラムの機能的に分離することができます。
というか、分離するのが「よいプログラム」です。
No.2
- 回答日時:
> v0 = float(input('初速度(km/h)を入力してください'))
> v0 = float(input('初速度(m/s)を入力してください'))
> のどちらが、現状にふさわしい速度の単位かわかりません。
それを決めるのは、あなたです。(あるいは、あなたにこのプログラムを作るように指示した人です)
Wikipediaの「砲口初速」(大砲の打ち出し速度)の説明では、毎秒m(m/s) で表記されています。
おそらく、他の資料でもm/s表記が多いのでしょう。
これをそのまま入力したいのなら、 ふさわしいのは m/sです。
野球でピッチャーの球速は km/hで表記されます。
自動車の速度はkm/hで表記されます。
投球の軌跡や、ジャンプ台から飛び出した自動車の軌跡といったものをシミュレートしたいのなら、 ふさわしいのはkm/h入力です。
> 変換せずに行うにはm/sで初速度を入力すれば良いでしょうか?
「変換せずに」したいのならそうです。
>・計算上の座標x,yと、canvas上の座標 xc,yc とを関連付ければということですが、
> 関連付けするとは具体的にどのようなコードを書くことでしょうか?
例えば。
1pixel=10m, キャンバスのcx=20を x=0mにしたい、という場合なら
cx = 10 * x + 20
拡大縮小率を掛けて平行移動分足します。
おそらく、canvasの縦は上が0と数学の座標と逆になっているので、合わせるなら
cy = -10 * y + 300
等とマイナスを掛ける必要があります。
No.1
- 回答日時:
・①②のような内容は、「自動で決まる」ものではなく、プログラムの設計段階で「決める」ものです。
・入出力と、計算とは分けて考えましょう。
重力加速度を g= 9.8 m/s^2 としているということは、長さは メートルを使わないと計算が合わなくなります。
※ 地球ではないどこかの星であれば別の単位かもしれませんが。
変数x,yをそのままcanvasの座標に使っているのなら、1pixel =1mになります。
こういうプログラムの場合は、入出力と計算を分けるのが常套手段です。
m,sを使って計算するプログラムを作るとして。
・初速度どんな単位で入力させたにしても、そこからm/sに変換して実行すればいい
・計算上の座標x,yと、canvas上の座標 xc,yc とを関連付ければ、1pixelを何mにするか、とか、どこに原点を持ってくるか、とか、上下左右反転、とかを物理シミュレーション部分に手を加える必要なく変更できます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) Pythonでのかんたんな物理シミュレーションについての書籍 5 2023/06/02 07:37
- その他(プログラミング・Web制作) 物理の斜方投射の目盛り線とx軸、y軸の追加について 3 2023/05/26 21:11
- その他(プログラミング・Web制作) ボールの動きがスムーズに動いてかつ目盛り線描画を維持するためには 4 2023/05/31 10:01
- その他(プログラミング・Web制作) 物理の斜方投射で目盛りに数値を入れたい 2 2023/05/27 06:32
- その他(プログラミング・Web制作) Pythonにおける物理のシミュレーションでの単位変換について 2 2023/06/02 17:11
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- 物理学 なめらかな水平面の床の上に、質量 200 g の物体がある。床の面を xy 面とし、鉛直方向に z 1 2022/07/23 11:28
- 物理学 2物体の単振動 1 2023/08/17 20:27
- 物理学 真空中に電位差Vに帯電した辺の長さlの正方形 の極板がある。 極板間の距離をdとする. いま, 初速 1 2022/11/24 16:07
- 物理学 力学の問題です。質量m1、速度v1の物体Aと質量m2、速度v2の物体Bがx軸上を等速直線運動していて 2 2022/12/24 13:26
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
*をユーザーが入力した数字の数...
-
正負を反転させて出力するプロ...
-
double型が正常に認識されてい...
-
C言語でつるかめ算をするにはど...
-
ワードで文字を入力する時の変...
-
電卓の小数点
-
C言語について。
-
scanf関数 バッファに残ったエ...
-
C言語の問題です。 整数を m, n...
-
小数か整数かを判定する方法
-
プログラミングの問題です 「金...
-
数字以外が入力されたらエラー...
-
ループ中でのscanfおよびcin
-
C言語の勉強しています。すみま...
-
VISUAL VASICがまったくわかり...
-
実行結果の順番がおかしいんで...
-
OpenCVの静止画保存のセルフタ...
-
漢字のソートについて
-
プログラミングの問題で、キー...
-
scanf関数を用いての標準演算子...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
double型が正常に認識されてい...
-
プログラミング初心者です。 Py...
-
正負を反転させて出力するプロ...
-
Excel VBAで、Application.Inpu...
-
C言語について。
-
batプログラム上で文字列を入力...
-
*をユーザーが入力した数字の数...
-
cout関数を使っているのですが...
-
漢字のソートについて
-
数字以外が入力されたらエラー...
-
Userformの入力順序をタブオー...
-
ワードで文字を入力する時の変...
-
Linuxで入力待ちなしkeyread関...
-
java初心者です。入力されたの...
-
EDITコントロールで入力できる...
-
Eclipseコンソール表示を、リセ...
-
小数か整数かを判定する方法
-
C言語scanf_sで何故か2回入力に...
-
VB.NETで16進数+16進数や16進...
-
Linuxプログラミングで、キーボ...
おすすめ情報
ディスプレイの設定は、解像度1900x1200で、
画面の拡大縮小はせず100%の場合と考えて教えて頂きたいです。
ご回答有難うございます。シミュレーション初心者なので重ねて質問させてください。
・重力加速度を g= 9.8 m/s^2 →長さはm
変数x,yをそのままcanvasの座標に使っているので1pixel =1mとなっているのですね?
・m,sを使って計算するプログラムを作るとして。
初速度どんな単位で入力させたにしても、そこからm/sに変換して実行すればいい
→v0 = float(input('初速度を入力してください'))
自分でこのように書いたのですが単位を考えていませんでした
はたして、
v0 = float(input('初速度(km/h)を入力してください'))
v0 = float(input('初速度(m/s)を入力してください'))
のどちらが、現状にふさわしい速度の単位かわかりません。
km/h単位で入力させたにしても、そこからm/sに変換して実行すればいいということですが、
変換せずに行うにはm/sで初速度を入力すれば良いでしょうか?
km/hからm/sに変換するのはkm/hの値に1000/3600をかければ良いのですね?
・計算上の座標x,yと、canvas上の座標 xc,yc とを関連付ければということですが、
関連付けするとは具体的にどのようなコードを書くことでしょうか?
・重力加速度を g= 9.8 m/s^2だから長さはm単位
変数x,yをそのままcanvasの座標に使っているのなら、1pixel =1m
v0 = float(input('初速度(m/s)を入力してください'))
これを決めるのが私なら速度はm/sにして10pixelを1mにしたいのですが、
どの部分でどうコードを書きかえればよいかわかりません、教えて頂けますでしょうか?
・>1pixel=10m, キャンバスのcx=20を x=0mにしたい、という場合なら
>cx = 10 * x + 20 拡大縮小率を掛けて平行移動分足します。
>おそらく、canvasの縦は上が0と数学の座標と逆になっているので、合わせるなら
>cy = -10 * y + 300
>等とマイナスを掛ける必要があります。
縦軸 canvas.create_line(0, i * 10,800, i * 10, fill = '#000000' if i==30 else '#d2d2d2')
横軸 canvas.create_line(i * 10, 0, i * 10,600, fill = '#000000' if i==1 else '#d2d2d2')
この目盛り線のx,y座標にcx,cyを代わりに代入してやれば良いということでしょうか?
こういう物理シミュレーションの場合、入出力と計算を分けるとはどういうことでしょうか?
入出力がどこの部分で、計算がどこの部分でしょうか?
おそらく計算はここの部分かとおもいますが。
x = x + vx0 * dt
v1 = vy
v2 = vy - g * dt
y = y + (v1+ v2) / 2.0 * dt
vy = v2
t = t + dt
Canvas座標系での座標変換は、具体的なCanvasの設定に依存する。座標系の原点(0, 0)はCanvasの左上隅に位置し、x軸は右向き、y軸は下向きとなる。
以下の関係式を使用して、2次元座標系(x, y)をCanvas座標系(X, Y)に変換できる。
X = x + X_offset
Y = canvas_height - y - Y_offset
ここで、X_offsetはCanvas内のx軸のオフセット(水平方向のシフト)を表し、Y_offsetはCanvas内のy軸のオフセット(垂直方向のシフト)を表す。また、canvas_heightはCanvasの高さ。
具体的なCanvasの設定に合わせて、X_offsetとY_offsetの値を調整する。これにより、2次元座標系(x, y)がCanvas座標系(X, Y)に正しく変換される。
ということですね。
Canvasのサイズが(800, 600)で、
1 pixelが10mを表すようにしたい場合
def pixel_to_meter(x, y):
X = 10 * x + 400
Y = -10 * y + 300
return X, Y
この関数は、引数として与えられたxとyの値を使って、ピクセル座標をメートル座標に変換する。
具体的には、x軸方向の変換では、xを10倍して400を足す。
y軸方向の変換では、yを10倍して-1をかけ、その後300を足す。
これにより、(x, y)のピクセル座標が、(X, Y)のメートル座標に変換される。
つまりこういうことなのですね?
あ、最後間違ってますね、
Canvasのサイズが(800, 600)で、
1 pixelが10mを表すようにしたい場合
def pixel_to_meter(x, y):
X = 10 * x + 400
Y = -10 * y + 300
return X, Y
この関数は、引数として与えられたxとyの値を使って、ピクセル座標をメートル座標に変換する。
これにより、(x, y)のメートル2次元座標が、(X, Y)のCanvas座標に変換される。
つまりこういうことなのですね?
勉強になりました有難うございます。