- ベストアンサー
C言語で空間上の四面体の体積を求める方法
- C言語で空間上の四面体の体積を求めるプログラムを作りたいんですが、どうすればいいのかわかりません。
- 構造体を使って空間上(三次元)の4点A,B,C,Dの座標を定義するのですが。
- 四面体の求め方もわかりません。ヘロンの公式じゃ求められませんよね(^^;
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
> (1/6)*(AB*AC)*ADを率直に求めて実行したのですが、結果がでません。 #1 のはじめに少し書いたのですが(分かりにくかったかもしれません), AB は A から B に向かうベクトルです。AC,AD についても同様です。 (AB×AC)・AD という風に '×' と '・' を使い分けているのには意味があります。 ベクトルの計算ですので C 言語でプログラムを書く場合,成分ごとに計算してやらないといけません。 今,AB の x 成分,y 成分,z 成分をそれぞれ,ABx, ABy, ABz としますと, ABx = (B の x 座標) - (A の x 座標) ABy = (B の y 座標) - (A の y 座標) ABz = (B の z 座標) - (A の z 座標) です。AC,AD についても同様です。 このとき, (AB×AC)・AD = (ABy*ACz - ABz*ACy)*ADx + (ABz*ACx - ABx*ACz)*ADy + (ABx*ACy - ABy*ACx)*ADz です。 これを使ってプログラムを書いてみてください。
その他の回答 (3)
- neKo_deux
- ベストアンサー率44% (5541/12319)
別の方法の案です。 厳密解で無くても良いという条件で、せっかくコンピュータで計算するのなら、モンテカルロ法のような方法を使ってみては? 簡単化のため、ABCD点のxyzの範囲を0~1とします。 乱数を使って0~1の中の適当な点を決めます。 その点が立体ABCDの内側であるかどうか判定。 面BCDに対して、点Aと同じ側か? 面ACDに対して、点Bと同じ側か? 面ABDに対して、点Cと同じ側か? 面ABCに対して、点Dと同じ側か? ならは、立体の内側であるとしてhit回数をカウント。 以上をtry回数だけ繰り返して、hit/tryを立体の体積の近似値とする。 ある程度の精度を期待するのなら、それなりの回数繰り返す必要がありますが、プログラムは作りやすいと思います。 最近のPCだと、かなりのマシンパワーが稼げるので…。 -- モンテカルロ法で円周率を求めよう http://www.f.waseda.jp/takezawa/math/Pi/monte.html
お礼
回答ありがとうございます。 モンテカルロ法というのを初めて知りました。 参考URLを見てもちょっと難しいですね(汗) 余力があればこちらの方法を使ってプログラミングしてみたいと思います。 アドバイスありがとうございました。
少し補足です。 スカラー三重積を計算するときは,AB と AC の外積を計算してから,AD との内積を取るよりも, AB, AC, AD の x, y, z 成分から直接,スカラー三重積を計算するほうがプログラムしやすいと思います。 http://www5.plala.or.jp/h-fuchi/math/vector/4.htm
お礼
2回も回答して頂きありがとうございます。 (1/6)*(AB*AC)*ADを率直に求めて実行したのですが、結果がでません。 ちゃんとprintfはしてるんですが。 たぶん自分のしょーもいミスだと思うんですけど。 URLはとても参考になりました。 スカラー三重積なんてあるんですね。 知りませんでした。 回答ありがとうございました。
三角錐の体積なので,底面積×高さ÷3 で求められます。 以下,AB,AC,AD はベクトルを表しているものとします。 まず ABC を底面とすると底面積は, (1/2)*|AB×AC| で求められます。 ここで,AB×AC は AB と AC の外積です。 次に,面ABCの単位法線ベクトルを n とすると, n = (AB×AC)/|AB×AC| であり,三角錐の高さは, n・AD (n と AD の内積) で求められます。 以上をまとめると三角錐の体積は, (1/6)*(AB×AC)・AD で求められます。 要するに AB, AC, AD のスカラー三重積の 1/6 です。 http://spinman.phys.metro-u.ac.jp/lecture/Mech/Vector/Vector.html A,B,C,D の位置関係によってはマイナスがつくかもしれないのでそのときは絶対値をとってください。 以上を素直にプログラムすればいいと思います。
お礼
再び回答ありがとうございます。 >ABx = (B の x 座標) - (A の x 座標) ABy = (B の y 座標) - (A の y 座標) ABz = (B の z 座標) - (A の z 座標) のそれぞれの成分を出すのを忘れていました。 たぶんこのまま出来ると思います。 アドバイスありがとうございました。