アプリ版:「スタンプのみでお礼する」機能のリリースについて

三次元上の点(px,py,pz)と
三角形(x1,y1,z1)(x2,y2,z2)(x3,y3,z3)の距離を求める方法を教えて頂けないでしょうか?

当方かなり数学が苦手でして、具体的に教えて頂けるとありがたいです。

質問者からの補足コメント

  • 教えて頂いた方法で、距離が求められました・・・
    上に、式を書きます。

    三角形の外にあるかどうかをどうやって求めればいいでしょうか・・・

    No.1の回答に寄せられた補足コメントです。 補足日時:2017/01/30 15:52
  • すいません。式は文字数オーバーになりました。

    点が三角形の外にあるかどうかをどうやって求めればよいでしょうか?

    https://www.geometrictools.com/Documentation/Dis …

    https://pdfs.semanticscholar.org/2058/5f20a0ad41 …

    が答えのようなのですが、よくわかりません。。

    わかる方よろしくお願い致します。

      補足日時:2017/01/30 15:56
  • うーん・・・

    >P = (x1,y1,z1) + s{(x2,y2,z2)-(x1,y1,z1)} +
    > t{(x3,y3,z3)-(x1,y1,z1)}

    これをどう展開して↓にすればよいのでしょうか?

    >を解いて s + t <= 1, 0 <= s, 0 <= t

    プログラムで確認しようとして、悩んでしまいました。
    よろしくお願い致します。

    No.4の回答に寄せられた補足コメントです。 補足日時:2017/02/01 17:01
  • へこむわー

    その3本の連立方程式を教えてもらってもよろしいでしょうか?

    X,Y,Z軸ごとに3本にするのは、違う気がするし・・・等、いろいろ考えたのですが・・・
    レベルが低くてすいません。。

      補足日時:2017/02/02 10:52

A 回答 (7件)

とりあえず、s, t の決定のところだけ。



P = (Px, Py, Pz) = (x1,y1,z1) + s{(x2,y2,z2)-(x1,y1,z1)} +
t{(x3,y3,z3)-(x1,y1,z1)} とすると

Px = x1 + s(x2 - x1) + t(x3 - x1)
Py = y1 + s(y2 - y1) + t(y3 - y1)
Pz = z1 + s(z2 - z1) + t(z3 - z1)

この方程式は2元の連立方程式ですが、方程式が3個あります。

P = (Px, Py, Pz) が三角形を含む平面上なら、ある方程式は
別の2本の方程式から導けるので、1本は余分です。
2本選んでs, t で解けば終わりです。

注意点は、例えば先頭の2本の場合

(x2 - x1)(y3 - y1) - (y2 - y1)(x3 - x1)=0 の場合は
#係数のたすきが0の場合
これはz軸から見て2辺が重なって三角形が潰れて見えるケースで、
解が得られないので、選ばないこと。

現実の計算では誤差があるので、「係数のたすき」の絶対値が
一番大きなものを選ぶなどの工夫が必要です。

ANO4の
>s と t の係数が共に 0 にならない

これは間違いでした。申し訳ない。
    • good
    • 0
この回答へのお礼

s + t が一番小さいものを選ぶでよろしいでしょうか?

下記で調べてみたところ、s+tの一番小さなものが1を下まわった場合、
三角形の面上に乗るようです。

//c#です。
public double comCalc(double px, double py, double x1, double y1, double A, double B, double C, double D, ref double s, ref double t)
{
t = (py - y1 + (x1 * C) / A - (px * C) / A) / (D - B * C / A);
s = (-x1 - t * B + px) / A;

return s + t;
}



double A = x2 - x1;
double B = x3 - x1;
double C = y2 - y1;
double D = y3 - y1;
double E = z2 - z1;
double F = z3 - z1;

double xy_s = 0; double xy_t = 0;
double xz_s = 0; double xz_t = 0;
double yz_s = 0; double yz_t = 0;

//s+tの結果
double xy_st = comCalc(px, py, x1, y1, A, B, C, D, ref xy_s, ref xy_t);//上記の関数に飛ぶ
double xz_st = comCalc(px, pz, x1, z1, A, B, E, F, ref xz_s, ref xz_t);
double yz_st = comCalc(py, pz, y1, z1, C, D, E, F, ref yz_s, ref yz_t);



・・・難しいです。

お礼日時:2017/02/02 17:14

>そうでなければ点と頂点の距離の中で最も短いもの。



すいません、この部分は駄目ですね。

三角形への垂線の足が三角形上でなければ、
各辺に垂線降ろして、足が三角形の辺上なら
その点までの距離、そうでなければ両端からの距離で短い方。
これを三辺で求めて最も短いもの選ぶ。
    • good
    • 0
この回答へのお礼

垂線をおろした点が三角形の内側になければ、計算対象外ということが
わかりました。

ありがとうございます。

お礼日時:2017/02/02 09:22

>これをどう展開して



s,t に関する3本の連立方程式になるので
2本選んで解くだけです。
    • good
    • 0
この回答へのお礼

その3本の連立方程式を教えてもらってもよろしいでしょうか?

X,Y,Z軸ごとに3本にするのは、違う気がするし・・・等、いろいろ考えたのですが・・・
レベルが低くてすいません。。

お礼日時:2017/02/02 09:23

三角形を含む平面に点からおろした垂線の足が三角形の内側なら


点と垂線の足との距離
そうでなければ点と頂点の距離の中で最も短いもの。

因みに点P が三角形の中にある判定は

P = (x1,y1,z1) + s{(x2,y2,z2)-(x1,y1,z1)} +
t{(x3,y3,z3)-(x1,y1,z1)}

を解いて s + t <= 1, 0 <= s, 0 <= t
を確認すればOK。3次元だと式が1個あまるので
s と t の係数が共に 0 にならない
2個を選んで解く。
この回答への補足あり
    • good
    • 0
この回答へのお礼

あ、すいません。追加の質問を↑にあげました。
よろしくお願い致します。

ご返答ありがとうございます。

お礼日時:2017/02/01 17:02

考え方の順番として、


まず、ある点と三角形の距離とは何でしょうか?

①点が三角形の中に含まれる時、距離は0であると言えます。
②三角形の存在する面を考え、その面に垂直な方向に三角形を動かしてできる三角柱と考えた時、点がこの三角柱の内部に存在する場合、点と面の距離がそのまま点と三角形の距離であると言えます。
③点が②の三角柱外に存在する時、三角形の中で最も点に近いのは、3辺上のどこかの点であると言えます。
③-A ③の場合において、3つの辺それぞれについて、辺に垂直な平面をその辺の端である2つの頂点で考えます。点がその2つの平面の間に存在する場合、点と三角形の距離は、点とその辺の距離とも表現できます。
点と直線の距離は求められますよね?
③-B Aにおいて2つの平面に含まれていなかった場合、点と最も近い、三角形上の点は、頂点のどれかということになります。点と点の距離は出せますよね?

このように、条件に当てはまるか判断し、当てはまる場合はその条件に従って、適切な計算を行うことで求めることができると思います。

が、今回の場合は具体的な数値ではありませんので、これらをまとめて表現する必要がありますね。
要するに、点と三角形の距離とは、点を中心とする球を考えて、その球をどんどん大きくした場合に、三角形にぶつかる瞬間の球の半径。ということです。
場合によっては球を考える前に三角形に含まれていたり、球を膨らませることで三角形の内部にぶつかったり、辺にぶつかったり、頂点にぶつかったり、具体的にどれになるかは先ほど上で示した条件によって変わるでしょう。
どこにぶつかろうとも、考え方としては1つ。ぶつかった瞬間の半径が距離なのです。
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。

・・・難しい。 とりあえず下記のZincerさんの方法で
やってみます。

お礼日時:2017/01/27 22:46

いきなり3次元で考えちゃダメ、2次元で考えよう。


(考え方は同じなので、簡単なほうで考えるのが基本です)

この時、いろいろなパターンが想定されますが、
それぞれについて考える。

まずは、
・三角形の辺の上に点があるパターン。(3次元では三角形の面にあるパターン)
・最短距離で三角形に線を引くと辺に垂直に交わるパターン。(3次元では更に…面に交わる…が加わります)
・上記の範囲外。
など、考えられる状態をいくつか考える。
それから、
・各パターンでどのようにすれば距離を求められるかを考える。
・各パターンでの求め方に共通のルールを見つける。
・そのルールで計算式を作る。
という過程を経て答えを導きだせばいい。

これすらも難しいというのであれば、
三角形ではなく線分として同様に考えてみましょう。


・・・余談・・・
誰かが示した解き方を丸暗記…では、簡単に忘れてしまうから意味がない。
それでは今目の前にある問題を先送りするだけで解決にはなりません。

数学は考え方を学ぶ学問とも言えます。
暗記に頼ることなく、理解をすることを心掛けてみましょう。
そうすることで考え方の引き出しが多くなり、そこに収められているツール(公式)を正しく使うことができるようになります。
(ツール…公式…が無ければその場で作ればいいしね。材料なんか必要ない。必要なのは時間だけ)

いきなりは難しいかもしれないけど、少しずつでいいのです。
がんばれ。
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。
おっしゃることが一番だと思います。

ただ、急に仕事で必要になりまして・・・

下記のZincerさんの方法でやってみます。

お礼日時:2017/01/27 22:45

三角形の場合は、領域が限定されていますので最近点を求める手間が加わりますが、



3点を通る平面の式は
http://mathtrain.jp/heimen

次に、その平面と点の距離の式は
http://mathtrain.jp/tentoheimen

となります。
最近点が3角形の内部にあればラッキー!
で終わりです。

それ以外の場合は他の数学専門家にお任せします。
この回答への補足あり
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます。
すいません。急に風邪をひきまして、月曜日にこの方法で
試してみます。

お礼日時:2017/01/27 22:43

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