3dのポリゴンの法線ベクトルを算出するプログラムなんですが
以下のプログラムに間違っている部分はあるでしょうか
何度か試してみたのですが何度か0で除算したりしてしまいます
渡す数字が悪いのか、プログラム自体が間違っているのかわかりません
少し助けてください

//法線ベクトル計算開始
x1=1つめの頂点のx座標
y1=1つめの頂点のy座標
z1=1つめの頂点のz座標
x2=2つめの頂点のx座標
y2=2つめの頂点のy座標
z2=2つめの頂点のz座標
x3=3つめの頂点のx座標
y3=3つめの頂点のy座標
z3=3つめの頂点のz座標

x4=x2-x1
y4=y2-y1
z4=z2-z1

x5=x3-x1
y5=y3-y1
z5=z3-z1

x6=y4*z5-y5*z4
y6=x4*z5-x5*z4
z6=x4*y5-x5*y4

//正規化
er=sqrt(x6*x6+y6*y6+z6*z6)
x6=er*x6
y6=er*y6
z6=er*z6

//終わり /法線ベクトル計算

このQ&Aに関連する最新のQ&A

A 回答 (2件)

ベクトルの外積の計算


---ここから---
x6=y4*z5-y5*z4
y6=x4*z5-x5*z4
z6=x4*y5-x5*y4
---ここまで---
は、
---ここから---
x6=y4*z5-y5*z4
y6=z4*x5-z5*x4
z6=x4*y5-x5*y4
---ここまで---
にしないとダメですね。y6の符号が逆です。これではベクトルの向きがおかしくなります。

あとは、「正規化」というのが、ベクトルの長さを1にすることだったら、
---ここから---
x6=er*x6
y6=er*y6
z6=er*z6
---ここまで---
これは、
---ここから---
x6=x6/er;
y6=y6/er;
z6=z6/er;
---ここまで---
にしないとダメですね。

ここで、3点が1直線上に並んでる場合は、外積が0になるので、0除算エラーになります。
そういう点の配置の時は「法線が求められるような点の配置になっていない」と言えますので、

erが0の時は、法線は計算不可能であるという例外処理を行う必要があるでしょう。

この回答への補足

すみません、大切なこと言うのわすっれました
実は 法線ベクトルを求めて、光とのベクトルのを求め面の色を出したりして
3Dのモデルを表示したかったのですが、回転行列を座標にかけると描画少しおかしいことになってしまいます。
回転行列の角度を90度にしたりすると光と面の角度を求めるところで0で除算ししたって出ます。
ちなみに描画しているのは、立方体のポリゴンで一辺が200(メタセコイア)で中心が(0,0,0)にあります

//回転行列 あってる?
//y軸
ループ 頂点の数
kaku=ラジアンに変換(0)←90にしたらaa/qqで0で除算する
その頂点のx座標=その頂点のx座標*cos(kaku)+その頂点のz座標*sin(kaku)
その頂点のz座標=その頂点のx座標*(sin(kaku)*-1)+その頂点のz座標*cos(kaku)
終了

//y軸の回転
ループ 頂点の数
kaku=ラジアンに変換(0)←90にしたらaa/qqで0で除算する
その頂点のy座標=その頂点のy座標*cos(kaku)+その頂点のz座標*(sin(kaku)*-1)
その頂点のz座標=その頂点のy座標*sin(kaku)+その頂点のz座標*cos(kaku)
終了

//法線求める
~省略~
//終了

x7=カメラ兼光源x座標
y7=カメラ兼光源y座標
z7=カメラ兼光源z座標

//面と光兼カメラとの角度
aa=1.0*x6*x7+y6*y7+z6*z7
qq=1.0*sqrt(x6*x6+y6*y6+z6*z6)*sqrt(x7*x7+y7*y7+z7*z7)

if aa/qq! > 0 {
  描画
  x座標とy座標だけを使う(奥行きは表現しない)
}

補足日時:2011/04/10 16:02
    • good
    • 0
この回答へのお礼

本当にお礼が遅くなって申し訳ございません
実際のところ、BA選ぶのも忘れてしまいました
本当にありがとうございました

お礼日時:2011/08/19 21:26

 プログラム中には割り算がないのでゼロ割が発生することはないと思います。


 er, x6, y6,z6 の結果を使うどこかで起きているのでは。デバッグシステムの中にはトレースしているポインタの位置とゼロ割を表示させるタイミングにずれがあるものもあります。
    • good
    • 0
この回答へのお礼

本当にお礼が遅くなって申し訳ございません
実際のところ、BA選ぶのも忘れてしまいました
本当にありがとうございました

お礼日時:2011/08/19 21:26

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q3次元ベクトルをある軸ベクトルで回転させたい

3次元ベクトルの求め方を教えてください。

下記図のように始点を軸ベクトルでθ(度)だけ回転したときの?の位置を求めたいのです。
これはどのような計算方法になるのでしょうか?なかなか思いつかなくて非常に悩んでいます。
アドバイスや回答をいただけたら助かります。よろしくお願いします。

Aベストアンサー

先ず、中心点(Sx,Sy,Sz)が原点にくるよう全体を平行移動させます。
(一番最後に元に戻します)
始点(Px,Py,Pz)は、(Px-Sx,Py-Sy,Pz-Sz)に移ります。この座標を(Px',Py',Pz')とします。

次に、回転軸ベクトル(Ax Ay Az)を回転させ、x軸に合致させます。それには二回の
回転変換が必要です。
最初に、ベクトル(Ax Ay Az)と、x軸方向単位ベクトル(1 0 0)のなす平面の法線ベクトルが
z軸に合うよう、x軸を回転させます(その角度をφとします)。
すると、回転軸ベクトルはx-y平面上に乗るので、それがx軸に合うよう、z軸を回転させます
(その角度をψとします)。

ベクトル(Ax Ay Az)と、x軸方向単位ベクトル(1 0 0)のなす平面の法線ベクトルは、(0 Az -Ay)。
x軸周りにφ回転させると、このベクトルは、
「1  0    0   「 0  =「      0
0 cosφ -sinφ   Az   Az・cosφ+Ay・sinφ
0 sinφ  cosφ」 -Ay」  Az・sinφ-Ay・cosφ」
で、z軸ベクトルに合うので
「      0      =「0
Az・cosφ+Ay・sinφ  0 
Az・sinφ-Ay・cosφ」  1」
これから、cosφ=-Ay/(Ay^2+Az^2)、sinφ=Az/(Ay^2+Az^2)
∴ φ=Arctan(-Az/Ay)

回転軸ベクトル(Ax Ay Az)は、
「1  0    0   「Ax =「      Ax      =「       Ax                   =「Ax 
0 cosφ -sinφ   Ay   Ay・cosφ-Az・sinφ   Ay・{-Ay/(Ay^2+Az^2)}-Az・{Az/(Ay^2+Az^2)}   -1
0 sinφ  cosφ」  Az」   Ay・sinφ+Az・cosφ」  Ay・{Az/(Ay^2+Az^2)}+Az・{-Ay/(Ay^2+Az^2)}」  0」
に変換され、x-y平面上に乗ります。これを(Ax' Ay' Az') とします。
つまり、(Ax' Ay' Az')=(Ax -1 0)

始点(Px',Py',Pz')もこの変換を受けるのですが、変換を全部纏めて後、一括変換させます。

今度は、x-y平面上に乗った回転軸ベクトル(Ax' Ay' Az')を、z軸の周りにψ回転させます。
「cosψ -sinψ 0 「Ax'  =「Ax'・cosψ-Ay'・sinψ =「Ax・cosψ+sinψ
sinψ  cosψ 0   Ay'   Ax'・sinψ+Ay'・cosψ   Ax・sinψ-cosψ
  0    0   1」  Az'」       Az'      」     0      」
これが、x軸ベクトルに合うので、
Ax・cosψ+sinψ=1
Ax・sinψ-cosψ=0
これから、cosψ=Ax/(Ax^2+1)、sinψ=1/(Ax^2+1)
∴ ψ=Arctan(1/Ax)

以上の回転の変換の積は、
「cosψ -sinψ 0 「1  0    0   =「cosψ -sinψ・cosφ  sinψ・sinφ
sinψ  cosψ 0   0 cosφ -sinφ   sinψ  cosψ・cosφ -cosψ・sinφ
  0    0   1」  0 sinφ  cosφ」   0     sinφ      cosφ   」

この変換を始点(Px',Py',Pz')に施します。
「cosψ -sinψ・cosφ  sinψ・sinφ  「Px' = 「Px'・cosψ-Py'・sinψ・cosφ+Pz'・sinψ・sinφ
sinψ  cosψ・cosφ -cosψ・sinφ  Py'   Px'・sinψ+Py'・cosψ・cosφ-Pz'・cosψ・sinφ
  0     sinφ      cosφ   」 Pz'」  Py'・sinφ+Pz'・cosφ               」 

この点を(Px”,Py”,Pz”)とします。

さて、ここでx軸に合った回転軸ベクトル(1 0 0)周りに(Px”,Py”,Pz”)を角度θ、回転させます。
「1  0    0   「Px” =「     Px”   
0 cosθ -sinθ   Py”  Py”・cosθ-Pz”・sinθ 
0 sinθ  cosθ」  Pz”」  Py”・sinθ+Pz”・cosθ」

これを(P_x, P_y, P_z)とします。

今度は、回転させた回転軸を元に戻す変換です。
回転の変換の逆行列は、行列各要素の余因子の行と列を入れ替えたものを行列式で割ったもので、
行列式は、(cosψ)^2+(sinψ)^2=1 なので、逆行列は
「 cosψ      sinψ        0  
-sinψ・cosφ  cosψ・cosφ   sinφ
sinψ・sinφ   -cosψ・sinφ  cosφ」

これを、(P_x, P_y, P_z)に施します。
「 cosψ      sinψ        0   「P_x =「P_x・cosψ+P_y・sinψ
-sinψ・cosφ  cosψ・cosφ   sinφ  P_y   -P_x・sinψ・cosφ+P_y・cosψ・cosφ+P_z・sinφ
sinψ・sinφ   -cosψ・sinφ  cosφ」 P_z」  P_x・sinψ・sinφ-P_y・cosψ・sinφ+P_z・cosφ」

結局、θ回転後のP点の座標は、
x座標 : P_x・cosψ+P_y・sinψ
y座標 : -P_x・sinψ・cosφ+P_y・cosψ・cosφ+P_z・sinφ
z座標 : P_x・sinψ・sinφ-P_y・cosψ・sinφ+P_z・cosφ
となります。

ここで、置き換えた変数を順次、元に戻します。
P_x、P_y、P_z を Px”、Py”、Pz” に、
Px”、Py”、Pz” を Px’、Py’、Pz’ に、
最後に、平行移動を戻して Px’、Py’、Pz’ を Px、Py、Pz に直します。

先ず、中心点(Sx,Sy,Sz)が原点にくるよう全体を平行移動させます。
(一番最後に元に戻します)
始点(Px,Py,Pz)は、(Px-Sx,Py-Sy,Pz-Sz)に移ります。この座標を(Px',Py',Pz')とします。

次に、回転軸ベクトル(Ax Ay Az)を回転させ、x軸に合致させます。それには二回の
回転変換が必要です。
最初に、ベクトル(Ax Ay Az)と、x軸方向単位ベクトル(1 0 0)のなす平面の法線ベクトルが
z軸に合うよう、x軸を回転させます(その角度をφとします)。
すると、回転軸ベクトルはx-y平面上に乗るので、それがx軸...続きを読む

Q3次元座標2点からの直線式の求め方

お世話になります。

3次元座標2点からの直線式(ax+by+cz=0)の求め方を教えて下さい。

2次元座標であれば、1つの傾きから算出できるのですが、3次元座標になると、X-Y平面、Y-Z平面での傾きの使い方がこんがらかってしまいます。
基本的な質問で申し訳ありませんが、よろしくお願い致します。

座標1 = (x1,y1,z1)
座標2 = (x2,y2,z2)

以上

Aベストアンサー

> 直線式(ax+by+cz=0)の求め方を教えて下さい。
3次元座標では(ax+by+cz=0)は原点を通る平面になり、直線の式ではありません。ax+by+cz=dは平面の一般式です。

2点を通る直線の式には公式があります。
以下のように簡単に導けます。
点(x1,y1,z1)を通り方向ベクトル(x2-x1,y2-y1,z2-z1)の直線ですから
媒介変数形式で
(x,y,z)=(x1,y1,z1)+t(x2-x1,y2-y1,z2-z1)
と成ります。
これを変形してすれば
(x-x1)/(x2-x1)=(y-y1)/(y2-y1)=(z-z1)/(z2-z1)
と3次元座標の直線の式となります。

Q線形代数の3次元空間での法線ベクトル、平面の方程式

線形代数の、3次元空間での法線ベクトル、平面の方程式の問題を教えて下さい
この問題が分かりません
3 次元空間において次の問いに答えなさい.
(1) 原点を含む法線ベクトル
1
  2
-1
の平面S の方程式を求めなさい
(2) 点(4, 5, 2) から平面S に垂線Lを下ろす. 直線Lの方程式とLとS の交点を求めなさい
(3) 直線Lを含み点(0, 0, 0) も含む平面の方程式を求めなさい
という問題です。皆さんお願いします
教えて下さい

Aベストアンサー

(1) 原点を含む法線ベクトル(1,2,-1) の平面S の方程式を求めなさい
>ベクトルを↑で表し、法線ベクトルを↑N(1,2,-1)とする。
S上の任意の点を(x,y,z)とすると、原点(0,0,0)がS上の点なので、
↑(x,y,z)は↑N(1,2,-1)と直交する。
よって内積を↑・↑で表すと↑(x,y,z)・↑N(1,2,-1)=x+2y-z=0
x+2y-z=0・・・答
(2) 点(4, 5, 2) から平面S に垂線Lを下ろす. 直線Lの方程式とLとS の交点を求めなさい
>直線L上の任意の点を(x,y,z)とするとuを実数として
↑(4, 5, 2)-↑(x,y,z)=u↑N=u↑(1,2,-1)だから
4-x=u、5-y=2u→(5-y)/2=u、2-z=-u→z-2=u
よって直線の方程式は4-x=(5-y)/2=z-2・・・答
x+2y-z=0に4-x=(5-y)/2→y=2x-3、4-x=z-2→z=6-xを代入
x+2(2x-3)-(6-x)=6x-12=0、x=2、y=2*2-3=1、z=6-2=4
よってLとS の交点は(2,1,4)・・・答
(3) 直線Lを含み点(0, 0, 0) も含む平面の方程式を求めなさい
>3点(0,0,0)、(4,5,2)、(2,1,4)を含む平面上の任意の
点を(x,y,z)とすると、u,vを実数として
↑(x,y,z)=u↑(4,5,2)+v↑(2,1,4)
要素を比較してx=4u+2v(ア)、y=5u+v(イ)、z=2u+4v(ウ)
(ア)(イ)からu,vをx,yで表すとu=(2y-x)/6、v=(5x-4y)/6
これらを(ウ)に代入して
z=2u+4v=2{(2y-x)/6}+4{(5x-4y)/6}=(3x-2y)
よって、3x-2y-z=0・・・答

(1) 原点を含む法線ベクトル(1,2,-1) の平面S の方程式を求めなさい
>ベクトルを↑で表し、法線ベクトルを↑N(1,2,-1)とする。
S上の任意の点を(x,y,z)とすると、原点(0,0,0)がS上の点なので、
↑(x,y,z)は↑N(1,2,-1)と直交する。
よって内積を↑・↑で表すと↑(x,y,z)・↑N(1,2,-1)=x+2y-z=0
x+2y-z=0・・・答
(2) 点(4, 5, 2) から平面S に垂線Lを下ろす. 直線Lの方程式とLとS の交点を求めなさい
>直線L上の任意の点を(x,y,z)とするとuを実数として
↑(4, 5, 2)-↑(x,y,z)=u↑N=u↑(1,2,-1)だから
4-x=u、5-y=2u→(5-y)/...続きを読む

Q「以降」ってその日も含めますか

10以上だったら10も含める。10未満だったら10は含めない。では10以降は10を含めるのでしょうか?含めないのでしょうか?例えば10日以降にお越しくださいという文があるとします。これは10日も含めるのか、もしくは11日目からのどちらをさしているんでしょうか?自分は10日も含めると思い、今までずっとそのような意味で使ってきましたが実際はどうなんでしょうか?辞書を引いてものってないので疑問に思ってしまいました。

Aベストアンサー

「以」がつけば、以上でも以降でもその時も含みます。

しかし!間違えている人もいるので、きちんと確認したほうがいいです。これって小学校の時に習い以後の教育で多々使われているんすが、小学校以後の勉強をちゃんとしていない人がそのまま勘違いしている場合があります。あ、今の「以後」も当然小学校の時のことも含まれています。

私もにた様な経験があります。美容師さんに「木曜以降でしたらいつでも」といわれたので、じゃあ木曜に。といったら「だから、木曜以降って!聞いてました?木曜は駄目なんですよぉ(怒)。と言われたことがあります。しつこく言いますが、念のため、確認したほうがいいですよ。

「以上以下」と「以外」の説明について他の方が質問していたので、ご覧ください。
http://oshiete1.goo.ne.jp/kotaeru.php3?qid=643134

Q回転行列から角度を求める

3Dのプログラミングを行っていますが、ある物体から得た回転行列から、ラジアンの角度を得たいと思っています。

物体はx軸・y軸・z軸にそれぞれ未知の値で回転させられており、
この物体から得られる回転行列Rは3×3の行列として
|r11 r12 r13|
|r21 r22 r23|
|r31 r32 r33|
と与えられています。ここから、x軸・y軸・z軸にそれぞれ何度回転させられているのかを算出するにはどのようにすればいいでしょうか?

参考資料が少ないため、ご教授お願いいたしますm(_ _)m

Aベストアンサー

先ほどの回答はアルゴリズムが複雑なのでもっと簡単な方法を考えてみました。
|r11 r12 r13|
|r21 r22 r23|=A
|r31 r32 r33|
として固有ベクトル v、固有値 λに対して
(A-λE)v=0
なので固有値λ=1のときvは軸の方向なので、
|r11-1 r12  r13 |
|r21  r22-1 r23 |・v=0
|r31  r32  r33-1|
なので(ri1-1 ri2  ri3) (i=1~3)は軸の方向を向いたベクトルとvと直交します。
そこで、0でないベクトルを取ります(ここではaとします)。
この軸と直交したベクトルを行列Aで回転させて、b=Aa とします。
もとのベクトルaとbが成す角度を求めます。
b・a = |a|^2 cosθ、|b×a| = |a|^2 sinθなので、
θ=atan2(|b×a|, b・a)が求める角度になります。

どうでしょう。

Q任意の面内にある点の座標から面の傾きを求める方法を教えて下さい。

任意の面内にある点の座標から面の傾きを求める方法を教えて下さい。

XYZ軸で構成される3次元空間があります。
そこに面Aが存在するとします。
この面Aの傾きを求めるためには
面A上にある座標、a(x1,y1,z1),b(x2,y2,z2),c(x3,y3,z3)の3点が分れば
傾きは求まるかと思います。
(実際は任意のxyの位置にある面Aの高さzを求めてa,b,cを決める)

この面を水平に補正しようとする場合の
x軸周りに?度、y軸周りに?度というのを求めたい場合
どのようにすればよいのでしょうか?

また実際は面Aにもたわみがありますので
もっとたくさんの点で面Aの高さを求め、
そこからx,y軸周りの傾きを近似する必要がありますが
その場合もどのようにすればよいのでしょうか?

ご回答、または参考サイトをお教えいただきたいと思います。

Aベストアンサー

#1です。補足します。
#1にて書いた通り私は詳細まで説明出来ません。直線近似については、直線を設定して各点と直線の距離の和が最小になるように傾きと切片を決定します。平面についても同じ原理です。各点と平面の距離が最小になるよう法線ベクトルと通過点を決定します。

Q法線ベクトルの基礎中の基礎

度々お世話になります。

直線のベクトル方程式とその法線ベクトルの関係で、
「直線ax+by+c=0において、n↑=(a,b)はその法線ベクトルである」との事ですが、このn↑=(a,b)というのは、成分表示ですから、n↑の始点を原点Oに取って、その終点の座標が(a,b)である、という捉えで良いのでしょうか。
例えば、次の基本的な問題

問 「二直線x+√(3)y-1=0…(1)、x-√(3)y+4=0…(2)について、
a,直線(1)(2)の法線ベクトルm↑、n↑のなす角θ。
b,二直線(1)(2)のなす鋭角α。
をそれぞれ求めよ」

を内積を使って計算だけで求めるのは教科書通りにやれば簡単に求まりますが、特に問題のbについて、自分で座標平面に作図してみたら、先の当方の捉え方ですと…
まず、n↑=(1,√(3))、m↑=(1,-√(3))ですから、これをそれぞれ始点を原点に取って、それぞれの座標通りに終点を取りますと、n↑が二直線(1)(2)の内部のm↑と交わらずII象限で交わってしまうのです。
解説を見たところ、bの問題は、円に内接する四角形の定理からαを求めているように見えるので、法線ベクトルn↑は四角形を作るように、m↑と交わらないと定理が成り立たない気がするのです。

という事は、n↑に限らず、法線ベクトルは、普通のベクトル同様に、位置は問題にせず、任意に平行移動しても良いということになるのでしょうか。
 計算間違いがあるかもしれないし、漠然とした内容の質問で申し訳ありませんが、アドバイス下さると有り難いです。
宜しくお願いします。

度々お世話になります。

直線のベクトル方程式とその法線ベクトルの関係で、
「直線ax+by+c=0において、n↑=(a,b)はその法線ベクトルである」との事ですが、このn↑=(a,b)というのは、成分表示ですから、n↑の始点を原点Oに取って、その終点の座標が(a,b)である、という捉えで良いのでしょうか。
例えば、次の基本的な問題

問 「二直線x+√(3)y-1=0…(1)、x-√(3)y+4=0…(2)について、
a,直線(1)(2)の法線ベクトルm↑、n↑のなす角θ。
b,二直線(1)(2)のなす鋭角α。
をそれぞれ求めよ」

を内積を使って計算だ...続きを読む

Aベストアンサー

こんばんわ。

方向ベクトルにしても、法線ベクトルにしても、
書かれているようなイメージでいいと思います。

方向ベクトルは考えている直線が進んでいく方向を表し、
法線ベクトルは考えている直線に対する垂線が進んでいく方向を表しており、
いずれも直線の方向を与えているだけです。

たとえば、直線の方程式が 2x+ 4y- 3= 0であれば、
法線ベクトルは n→= (2, 4)と表すことになりますが、
n→= (1, 2)としても「その進んでいく方向」は同じであり、これも法線ベクトルと言えます。
さらに、-1を乗じた n→= (-1, -2)も法線ベクトルと言えます。
値というよりも「比」がポイントなのです。


「なす角」を考える問題では、質問に書かれているとおり「平行移動」させて構いません。
2直線の交点となる点を原点まで平行移動させているイメージになります。


最後に「方向ベクトル」に関する過去の質問を参考URLとしてつけておきます。

参考URL:http://oshiete.goo.ne.jp/qa/6229779.html

Q平面のベクトル内積=0で垂直になる理由?

平面と平面の位置関係が垂直になる時、内積がゼロになることに関しまして、

なぜなのかを、可能ならば 直感的に理解したいです。

ベクトルの基本は勉強しましたが・・・ 

突然、「垂直ならば この計算の答えがゼロになる」 と教わっただけで、まだ腑に落ちないでいます。

もしも良い説明がありましたら、よろしくお願いいたします。

Aベストアンサー

>なぜなのかを、可能ならば 直感的に理解したいです。

visualにいうこととして、幾何学的に考えてはどうですか。

ベクトルA↑とベクトルB↑の内積IPは

IP=A↑・B↑=|A↑||B↑|cosθ

であって|A↑|、|B↑|はベクトルの大きさ、θはA↑、B↑のなす角度です。

IP=A↑・B↑=0



θ=90°

を意味することが解ります。

いいかえるとIP=A↑・B↑はA↑がB↑に落とす影(射影)であって、垂直なら影が0ということです。

0でない場合はA↑とB↑は平行成分を有して、相互に影を落とすということです。


人気Q&Aランキング