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

Cの初心者です。

空間上に存在する2点間を結ぶ直線上に任意の点が存在するかどうかの
関数を作りたいのですがどのような公式を用いて評価すればいいのか分かりません。
どなたかご教示ください。

引数
   始点 A(x,y,z)
   終点 B(x,y,z)
   直線上に存在するであろう任意の点
      C(x,y,z)

 関数のイメージ
   boolean isOnLine (Ax, Ay, Az, Bx, By, Bz, Cx, Cy, Cz); 配列でもよいです。

返り値
   True、 False  ( 0 or 1 )

よろしくお願いします。

A 回答 (8件)

直線ABの式を求め、その式に任意の点Cの座標を代入し、式が成り立つか判定すればOK。



(Cx,Cy,Cz)=(Ax,Ay,Az)+t(Bx-Ax,By-Ay,Bz-Az)
この式が、点Cを通る直線ABの式。

この式をt=の形に直せば
t=(Cx-Ax)/(Bx-Ax)=(Cy-Ay)/(By-Ay)=(Cz-Az)/(Bz-Az)
となる。

2つの点{(Cx-Ax)、(Cy-Ay)、(Cz-Az)}、{(Bx-Ax)、(By-Ay)、(Bz-Az)}は「点Aが原点になるように、直線ABと点Cを並行移動した時の、点Bと点Cの座標」を表わしている。

そして、原点と点Bの延長線上に点Cがあるならば各x、y、zの比は等しくなるので
(Cx-Ax):(Cy-Ay):(Cz-Az)=(Bx-Ax):(By-Ay):(Bz-Az)
が成り立つ。

つまり
(Cx-Ax)/(Bx-Ax)=(Cy-Ay)/(By-Ay)=(Cz-Az)/(Bz-Az)
が成り立つ。

プログラムでは
(Bx-Ax)が0、かつ、(By-Ay)が0、かつ、(Bz-Az)が0
(Bx-Ax)が0、かつ、(By-Ay)が0
(Bx-Ax)が0、かつ、(Bz-Az)が0
(By-Ay)が0、かつ、(Bz-Az)が0
(Bx-Ax)が0
(By-Ay)が0
(Bz-Az)が0
と言う7つの例外条件を取り除いた上
(Cx-Ax)/(Bx-Ax)と(Cy-Ay)/(By-Ay)と(Cz-Az)/(Bz-Az)が等しいかどうかを判定すれば良い。

7つの例外条件では、それぞれ

(Bx-Ax)が0、かつ、(By-Ay)が0、かつ、(Bz-Az)が0
の時
(Cx-Ax)が0、かつ、(Cy-Ay)が0、かつ、(Cz-Az)が0
ならば真(3つの点がすべて同じ座標にある)

(Bx-Ax)が0、かつ、(By-Ay)が0
の時
(Cx-Ax)が0、かつ、(Cy-Ay)が0
ならば真(直線ABがZ軸と並行)

(Bx-Ax)が0、かつ、(Bz-Az)が0
の時
(Cx-Ax)が0、かつ、(Cz-Az)が0
ならば真(直線ABがY軸と並行)

(By-Ay)が0、かつ、(Bz-Az)が0
の時
(Cy-Ay)が0、かつ、(Cz-Az)が0
ならば真(直線ABがX軸と並行)

(Bx-Ax)が0
の時
(Cx-Ax)が0、かつ、(Cy-Ay)/(By-Ay)と(Cz-Az)/(Bz-Az)が等しいならば真(直線ABが「平面(Bx-Ax)=0」上にある)

(By-Ay)が0
の時
(Cy-Ay)が0、かつ、(Cx-Ax)/(Bx-Ax)と(Cz-Az)/(Bz-Az)が等しいならば真(直線ABが「平面(By-Ay)=0」上にある)

(Bz-Az)が0
の時
(Cz-Az)が0、かつ、(Cx-Ax)/(Bx-Ax)と(Cy-Ay)/(By-Ay)が等しいならば真(直線ABが「平面(Bz-Az)=0」上にある)

と判定すればよい。

なお、この判定では「点Cが直線ABの延長線上にあり、点Aと点Bの中間にない場合(線上にあるが外側にある場合)」にも真となる。

点Cが点Aと点Bの中間にあるかどうかは「Ax、Bx、Cxの大小関係」で判定可能なので、上記の判定の前に判定してしまうと良い(Ay、By、Cy、Az、Bz、Czの大小関係は無視して良い)
    • good
    • 0

えぇと....


ベクトルの取り方を確認して下さい>#7. #5 では「AB と AC」なのでなす角は 0 です. もちろんこれだと「C が B より A に近い」という条件を組み込まなければなりません. 一方, #3 のように「CA と CB」でとればなす角が π というだけですみます.
いずれにしても「角度を求める」という方針だと「C と A または B が一致する」可能性を念頭に置く必要がありますね.
ああ, 線分だったら Line より LineSegment (もしくは Segment) の方がいいかもしれない.
というか, この辺はほとんど数学の問題であって, 全く C には関係ない気がする.
    • good
    • 0

No.5の方の内容に補足させてください。



ABの線分上にCが存在するかどうかなので、
θ=180度で、cosθ = -1 の場合 じゃないかと思います。

ABの直線上にCがあるかだと、cosθ = -1 or 1 ですね。
    • good
    • 0

計算方法についてはみなさんがおっしゃるとおりですが、関数の使われ方によっては誤差の処理が必要でしょうね。

    • good
    • 0

> ところでその"二つのベクトル AB と AC の内積から求められる"とは


> 具体的にどのようにどのような公式になるのでしょうか?

ベクトルABを x, ベクトルACを y とします。
x・y = |x||y|cosθ なので
cosθ= (x・y) / (|x||y|)
二つのベクトルが重なるときθ=0だから、cosθ = 1 すなわち
(x・y) = |x||y|
    • good
    • 0

一応確認しておきたいのですが, 判定したいのは


・AB を通る直線上に C が存在するかどうか
・AB を端点とする線分上に C が存在するかどうか
のどちらでしょうか?
後者の方がちょっとだけ面倒なので.

この回答への補足

ご確認ありがとうございます。

当方が行いたいのは後者の方です。
よろしくおねがいします。

補足日時:2009/08/25 14:45
    • good
    • 0

答えがひとつ出ているようですが、内積を使う場合の参考に。



http://w3e.kanazawa-it.ac.jp/math/category/vecto …
「ベクトルのなす角」に関する説明ページです。

Cx, Cy, Czを原点として、Ax,Ay,Azに向かうベクトル、
Cx, Cy, Czを原点として、Bx,By,Bzに向かうベクトル のなす角が、
180度であれば、直線上にCx,Cy,Czがあると判定できます。
    • good
    • 0

二つのベクトル AB と AC の内積から求められるのでは?

この回答への補足

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

ところでその"二つのベクトル AB と AC の内積から求められる"とは
具体的にどのようにどのような公式になるのでしょうか?

中学高校の数学を忘れてしまって全然思い出せません。
ご教示頂けませんか?

補足日時:2009/08/25 13:08
    • good
    • 0

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

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