• 締切済み

2物体の衝突について

ただいま物理エンジン(2D)を作ろうとしています。 そこでどうしてもわからないことがありまして・・・ これは平面上のお話です。 線分AB、CDがあります。 各点の座標をA(a1,a2)、B(b1,b2)、C(c1,c2)、D(d1,d2)とします。 線分ABはE(e1,e2)を中心に毎秒fラジアンで、 線分CDはG(g1,g2)を中心に毎秒hラジアンで回転しております。 その上線分ABと点Eのセットは毎秒(i1,i2)の速度で、 線分CDと点Gのセットは毎秒(j1,j2)の速度で等速直線運動しております。 このとき、線分ABとCDは何秒後にぶつかるのか、もしくはぶつからないのか、 その解き方を教えてください。 よろしくおねがいします。。。

みんなの回答

回答No.4

改めて読み直してみたら、誤解があるようなので。 x 秒後って、1秒とか2秒とかに限定されないですよ。 0.1秒間隔でも、0.01秒間隔でも、「繰り返して」みれば いいわけです。わざわざ、繰り返し計算が取り柄の機械を 使うわけですから。 ※本当は、小さい単位で繰り返すと誤差の問題がでてくる けど。 ※あと、この程度の問題なら、それこそ Excel でおおざっ ぱに計算してロジックの確認くらいは、数時間でできると 思う。 あと、本当に初期段階なら、ぶつかったかどうかの判定で はなく、その時々の線分 AB と BC の距離も出力しましょ う。それをファイルに出力して、Excel でも(もっと専門 的なツールでも)使ってグラフにしてみれば、「このあた りでぶつかっていそう」というのはわかります。 そういう数値計算で、「あたり」をつけてから、きっちり やってみるというのも手です。 そういうのを試行錯誤といいます。 試行錯誤も計画的にやると、いろいろと勉強になります。

回答No.3

本当は、「ぶつからない」という判断もそんなに難しくありません。 まず、線分の動きから、回転中心点相互の距離が、 1)点Eと線分ABの中点までの距離+線分ABの長さの1/2 2) 点Gと線分CDの中点までの距離+線分Cdの長さの1/2 としたときに、1) + 2) を超えた場合、線分は交わらないことがわかります。 一方で、中心点、E, G の距離変化は、次の2パターンしかありません。 ・時間経過とともに、単調に増加する ・時間経過とともに、単調に減少し、最小点を通過すると、その後単調に増加する。 いずれにしても、距離の変化が「増加」に転じた後、「中心点が離れすぎた」ところで、 線分が交わらなければ、「ぶつからない」ということです。 ここまで、「やってみる」方式。 交わるかどうかだけでも判定したいというのであれば、中心点の移動だけに限定して、 調査するのも手です。 これだと、 点 E = (e1, e2) + t(i1, i2) 点 G = (g1, g2) + t(j1, j2) の距離(の自乗)を調べるだけですから、tに関する2次関数の微分だけでも、距離が 最短になる時間は決定できます。 このときの、E G の距離が、「ぶつかる」条件を満たさなければ「ぶつからない」(十分条件) 「ぶつかる」条件を満たすなら、その前後の t で、シミュレーションをすればいいかもしれません。

回答No.2

物理エンジンを作ろうという話であれば、「解く」というより、「やってみる」というのも手なのですが。 struct position { double x; double y; }; class lineType { private: position start; // 始点の座標 position end; // 終点の座標 position roteCenter; // 回転の中心座標 public: lineType(position aStart, position aEnd, position aRoteCenter); move(position pos); // pos の指定量移動する rote(double radian); // roteCenter を中心に radian だけ回転する friend boolisCoss(lineType a, lineType b); // a と b が接触しているかどうかの判断 // 接触判定に private メンバーが必要なので、friend 指定 }; bool isCoss(lineType a, lineType b) { この関数の実体はここに必要 } こんなのを作って、 lineType AB(positon(a1, a2), position(b1, b2), position(e1, e2); lintType CD(positon(c1, c2), position(d1, d2), position(g1, g2); に対して、 x sec 後の位置は、 AB.move(position(i1 * x, i2 * y); AB.rote(h * x); CD も同様にしたあと、 isCoss(AB, CD); で接触しているかどうか判定します。 そぞれぞれの計算は基本的なものですから、これを組み合わせて目的が達成できるのが、オブジェクト指向の有用なところです。 ただ、あくまでも、x秒後の様子を計算するだけなので、「実はぶつからない」という判断は、これだけではできません。 それぞれの line をビジュアルで表示できれば、見た目で判断できるとは思いますが。

RedHat3104
質問者

お礼

んー・・・ まあ初めそれを思いついたんですけど、 でももしかしたらx秒後以内にぶつかってx秒後には通りすぎてしまっている ということもなくはないかな?と考えまして。。。 しかし物体をクラスにまとめるってとこを参考にしようかなと思います。 >それぞれの line をビジュアルで表示できれば、見た目で判断できるとは思いますが。 コンピュータにそんな機能があればなぁ・・・

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

Cとは関係なく、数学の問題だと思うんですが.... 1)t(t≧0の実数)秒後の各座標をtを使って表現してみる。 例えば、R(θ)をθラジアンの回転行列だとすると、 t秒後Aの座標Atは At=(A-E)・R(f×t)+Et ここで、A,Eは初期座標、Etはt秒後のEの座標 2)線分AtBt,CtDtの交点を求める。 3) 2を満すtの実数解が存在すれば衝突する。 各式の意味や細かい計算は、物理エンジン作ろうというくらいだから、説明しなくても大丈夫ですよね?

RedHat3104
質問者

お礼

やはり行列が出てきましたか。。。 行列を勉強してからもう一度このご回答を見てみます。 ありがとうございました。

関連するQ&A