質問: 3次元の平面上の点かどうかを判定したい 3次元空間の3点で三角形を作って、その三角形上に点があるかどうかを判定したいのですが、どうすればよいでしょうか? 例えば3点、a(0,0,0),b(10,0,0),c(0,10,0)で三角形abcをつくったとき、(0,1,1)はabcの平面上、(0,10,10)は平面外という風に判定したいです。
回答: #2#6です。 >>> そうです!△abcの内部ということです。 例として書いたのは「△abcの内部」ということを分かってもらうために簡単なものを書きました。 なので、例の3点だけでなく、任意の△abcの内部にたいして、任意の点を判定するには、どうすれば良いでしょうか? 私は公式を覚えるのが不得意な人間なので、あくまでも「前回回答までのような考え方を踏襲」してやりたいと思います。 ------------- では、やってみましょうか。 ただし、私は、計算が非常に不得意(笑)←マジ なので、 以下の手順は検算(検証)してみてください。 三角形△abcの3頂点が、 a(xa, ya, za) b(xb, yb, zb) c(xc, yc, zc) であり、 判定対象の点は x(x, y, z) であると置きます。 まず、点aが原点(0,0,0)になるように、全部の点を平行移動します。 a' ≡ o (0, 0, 0) b' (xb-xa, yb-ya, zb-za) ≡ ベクトルob'→ = b→ c' (xc-xa, yc-xa, zc-xa) ≡ ベクトルoc'→ = c→ x' (x-xa, y-xa, z-xa) ≡ ベクトルox' → = x→ このとき、 x→ = [0~1]×b→ +[0~1]×c→ であれば、xは△abcの内部(辺の上も含む)です。 x→ = アb→ + イc→ (0≦ア≦1,0≦イ≦1) したがって x -xa = ア(xb - xa) + イ(xc - xa) y -ya = ア(yb - ya) + イ(yc - ya) z -za = ア(zb - za) + イ(zc - za) ここで、未知の数は、アとイだけです。 つまり、解が2個しかないのに、3本の式があるという、へんてこりんな連立一次方程式です! ですから、 1本目の式と2本目の式から、アとイを確定させて、それが3本目の式と矛盾していないかを調べれば、点xが三角形の内部であるかどうかが判定できます! ------------------------------------------------------ 1本目の式より、 (x -xa)(yb-ya) = ア(xb-xa)(yb-ya) + イ(xc-xa)(yb-ya) 2本目の式より、 (xb-xa)(y-ya) = ア(xb-xa)(yb-ya) + イ(xb-xa)(yc-ya) 引き算すれば、 (x -xa)(yb-ya) - (xb-xa)(y-ya) = イ(xc-xa)(yb-ya) - イ(xb-xa)(yc-ya) = イ{(xc-xa)(yb-ya) - (xb-xa)(yc-ya)} よって イ = {(x -xa)(yb-ya) - (xb-xa)(y-ya)}/{(xc-xa)(yb-ya) - (xb-xa)(yc-ya)} これを再び1本目に代入すれば、 x -xa = ア(xb - xa) + (xc - xa){(x -xa)(yb-ya) - (xb-xa)(y-ya)}/{(xc-xa)(yb-ya) - (xb-xa)(yc-ya)} よって、 ア =[ (x -xa -(xc - xa){(x -xa)(yb-ya) - (xb-xa)(y-ya)}/{(xc-xa)(yb-ya) - (xb-xa)(yc-ya)}]÷(xb - xa) さらに、上の上の上の式に代入すれば、 イ = ・・・(略) こうして求めたアとイがそれぞれ、0から1の範囲内に入っていれば、第1、第2段階はクリア。 残る第3段階は、それらを3本目の式に代入して、左辺と右辺がぴったり一致していれば、第3段階(=最終段階)もクリアです。 ------- なお、 もしも点a(xa, ya, za)が最初から原点(0,0,0)であれば、 x = ア・xb + イ・xc y = ア・yb + イ・yc z = ア・zb + イ・zc 1本目の式より、 x・yb = ア・xb・yb + イ・xc・yb 2本目の式より、 y・xb = ア・xb・yb + イ・xb・yc 引き算。 x・yb - y・xb = イ・(xc・yb - xb・yc) イ = (x・yb - y・xb)/(xc・yb - xb・yc) ↑これが0~1の範囲か? この判定結果が合格ならば、次、 1本目の式にイを代入。 x = ア・xb + xc (x・yb - y・xb)/(xc・yb - xb・yc) 移項。 ア・xb = x - xc (x・yb - y・xb)/(xc・yb - xb・yc) = {x(xc・yb - xb・yc) - xc (x・yb - y・xb)}/(xc・yb - xb・yc) = {x(0 - xb・yc) - xc (0 - y・xb)}/(xc・yb - xb・yc) = xb・(y・xc - x・yc) /(xc・yb - xb・yc) よって、 ア = (y・xc - x・yc) /(xc・yb - xb・yc) ↑これが0~1の範囲か? この判定結果が合格ならば、次、 以上で求めた ア=* と イ=* を、3本目の式 z = ア・zb + イ・zc に代入してみる。 ↑これで、左辺と右辺がピタリと一致するか? この判定結果が合格ならば、全条件クリア。 ------------------------------------------------------ 他の考え方も紹介しましょう。 その考え方とは、「影踏み」です。 三角形の内部に点があるためには、 z=0の点だけを集めた平面(xy平面と言う)に対して、垂直方向から光を当てたとき、xy平面というスクリーンに投射された影ににおいて、点は、三角形の内部に入っていないといけません。 つまり、z座標を無視して、x座標とy座標だけを見て2次元で考えればよいです。 これを式で書けば、 ベクトル(x-xa,y-ya) = ア×ベクトル(xb-xa, yb-ya) + イ×ベクトル(xc-xa, yc-ya) ということは、1本目の式は、 x -xa = ア(xb - xa) + イ(xc - xa) ↑ この式、どっかで見たことありませんか? (以下、略) いずれにしろ、上記のような地道な作業になりそうです。 色々な点xの座標について確かめたければ、表計算ソフトにぶちこめばよいでしょう。