プログラミングと物理

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

プログラミングと物理

投稿記事 by GRAM » 14年前

自分は物理が比較的得意ですが、
今のところプログラミングでバリバリとシミュレーションして結果を観察・・・ということは全くといいほどできていません。

・・・よくよく考えたらそんな知識はまだない。よくてもあと2年くらい頑張らないと。(とくに流体とか連続体とか)
しかし、まぁその手の物理そのものに関する知識があったところで、高校生でもわかるレベルの基本的なことをするにしても
プログラミングのノウハウのほうがなければどうしようもないのもまた事実
ということでこれからちょくちょく習ったこととか思いついたこととかを日記に書いていくかもしれません
(めんどくさくなってやめるかもしれません)

目指すは物理演算ライブラリの自作!(まぁ10年スパンの話だろうけどw)

さて、何をするにしてもまずは道具がいるのでちょっと頑張って作ってみました。
というより、勉強中のTMP(テンプレートメタプログラミング)の作品第一号です
その名もPhy型
物理演算において若干めんどくさい、そもそも計算が合ってるのか(つまり次元が一致しているのか)どうかということを勝手にコンパイル時にチェックしてくれるという奴です
まぁどうせ試作段階なので、ガタがすぐに出てくるでしょうけれど、とりあえずコードを組んでみます
記念すべき初コードでは高校で一番最初に習う「等加速度運動」、もしくは単純に「自由落下」をシミュレーションしてみます

CODE:

#include 
#include "Phy.h"
#include "Phy\PhyLinear.h"
#include "MyVector.h"
using namespace Physics;
using namespace Linear;

//時間変化は1/60秒
static const Phy dt(1.0/60.0);

//10ピクセルを1mとする
static const Phy toPixel(20.0);

//重力加速度を指定
static const Vector> gAccel(0.0,9.8,0.0);

//重さ10キログラムの円を仮定
class Circle{
public:
	Circle():s_(10.0,0.0,0.0),m_(10.0){
	}
	void Update(){
		AddForce(gAccel*m_);
		a_ = f_/m_;
		v_ += dt * a_;
		s_ += dt * v_;

		f_ = Vector>(0.0, 0.0, 0.0);
	}

	void AddForce(const Vector> &f){
		f_ += f;
	}
	Vector> GetPosition(){
		return s_;
	}
private:
	//位置
	Vector> s_;
	//質量
	Phy				m_;
	//速さ
	Vector > v_;
	//加速度
	Vector> a_;
	//このオブジェクトにかかる力のバッファ
	Vector > f_;
};



int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
		Circle c;
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
			c.Update();
			Vector p = c.GetPosition()*toPixel;
			DrawCircle(p.x, p.y, 10,0xff0000,1);
        }
        
        DxLib_End(); // DXライブラリ終了処理
        return 0;
}  
Phy型とVectorクラスのコードは面倒なのでのっけませんが、後者は単にベクトル演算をしてくれる型です。
(C++を初めて最初に書いたクラスなので、書き直したいところも結構ありますが、今のところ使えるので放置してます)

面倒なことをしていると感じられる方もいるかもしれませんが、やってること自体は極めて単純です

ニュートンの運動方程式
ma = F
を再現しています。
Fは力ですが、この場合重力、すなわち
重力加速度x質量
の値が毎フレーム与えられています

次に毎フレームごとに円の位置情報を更新します
まずは加速度を求めます
a = m/F

次に求めた加速度x時間を速度に足します
v += a*dt

そして位置に速度x時間を加えます
s += v*dt;

以上です。
あとは表示するだけという感じですね
わざわざ質量x重力加速度をしてからまた質量で割っているのは、あとあと楽になりそうな予感がしたからです
確信はありません。単純に予想と直観ですね。
敢えて言うならば、ほかに力が加わった場合、AddForceを外部から呼び出せば簡単に力の合成ができるからです。

さて非常につまんないので、気が向いたらもうちょっとましな奴を考えてみます。

ピンボールくらいまではすぐ行けそうな予感。
変形とかはどうかな~。アイディアはあるけれど実践できるかどうか。
摩擦とかが意外と大変そうな予感。いろいろと試さなければ。

プロジェクトをさらしてみます
添付ファイル

[拡張子 zip は無効化されているため、表示できません]


アバター
へろりくしょん
記事: 92
登録日時: 14年前

Re: プログラミングと物理

投稿記事 by へろりくしょん » 14年前

私見ですが、物理学を嗜む方は、意外とものが見えてないような気がします。

例えば、ここに急速に引かれあっている2人の男女がいたとして、それが他の第三者と比較して、より強い力を有しているのかというとそうでもありません。
また、質量が同じであるなら、より早い速度でぶつかった方が強い衝撃を受けるかと言うと、そうでもありません。 相手とシチュエーションによります。

以前どこかのサイトで、駅のホームの階段において、もっとも美しくパンチラが見える角度というのを計算されていた方がいましたが。
この方もやはり、どこか間違ってる気がします。


とりあえず、私はタンスの角で小指をぶつけるよりも、ことある毎に何かに触れてはひりひりする、右手中指の原因不明の切り傷の方がよっっっぽどイライラします。
計算上、タンスの角にぶつけた小指の方が圧倒的に痛いはずです。
人は言います「ドアで挟むよりマシだろ?」と、いいえ。 そんな事はありません。 痛いものは痛いのです。 もう、ホント油断してたらチクッ、ちょっと気が逸れてる隙にピリッ。 もううんざりです。
この痛さは計り知れません。 計り知れない上にどんぶり勘定です。 誰かカルシウムください。

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

Re: プログラミングと物理

投稿記事 by GRAM » 14年前

>>へろりんさん
またアバターが変わりましたね
梅雨仕様ですか?

カルシウムは自分も足りてないと思います

アバター
tk-xleader
記事: 158
登録日時: 14年前

Re: プログラミングと物理

投稿記事 by tk-xleader » 14年前

「型に単位を含める」というのはテンプレートメタプログラミングのテーマの一つですね。
boost.unitsがちょうど同じ目的のライブラリですので、参考にされてみるといいとおもいますよ。