平田智剛のブログ

立法、行政、司法、報道、そして科学

F.ism.does_harm_to(!F);

視円錐のベクトル方程式を求めてみる。

 C=\left(  \begin{array}{a}1 \\ 1 \\ 1 \end{array} \right) から点  T'\left(  \begin{array}{a}3+1 \\ 4+1 \\ 12+1 \end{array} \right) を中心に視野角60度で眺めたときの視円錐のベクトル方程式を求めよ


まず視心のベクトル方程式を求める。

視心上の点 Dは次の条件を満たすはずだ。
 \overrightarrow{OC} + k'\overrightarrow{CT'} = \overrightarrow{OD} 但し k'は正数。

次に、視心上で、 Cから距離1である点 Tを求めよう。
 \overrightarrow{CT} = \frac{\overrightarrow{CT'}}{|\overrightarrow{CT'}|} = \frac{\left(  \begin{array}{a}3 \\ 4 \\ 12 \end{array} \right)}{13}
(なので、
 T = \left(  \begin{array}{a}1 \\ 1 \\ 1 \end{array} \right) + \frac{1}{13}\left(  \begin{array}{a}3 \\ 4 \\ 12 \end{array} \right) = \frac{1}{13}\left(  \begin{array}{a}16 \\ 17 \\ 25 \end{array} \right))

よって、視心のベクトル方程式は次のように書き換えることもできる。
 \overrightarrow{OC} + k\overrightarrow{CT} = \overrightarrow{OD} 但し kは正数。

数値を代入すると、
 \left( \begin{array}{a}1 \\ 1 \\ 1 \end{array} \right) + \frac{k}{13}\left(  \begin{array}{a}3 \\ 4 \\ 12 \end{array} \right) = \left( \begin{array}{a}x \\ y \\ z \end{array} \right)

この式は、 Cから T(')の方向に kだけ進んだ点 D(k)の座標を示している。
視心上の各点 D(k)=f_{C,T}(k)が、視心と垂直な方向に、何らかの大きさを持つ円(自身を中心とする)を描いていると考えることで、視円錐は実現する。
f:id:ec084:20200820025946p:plain この円上の点 Pをベクトル方程式で表現してやればよいのだ。
円の半径 rは、 kと視野角(画角)によって決まる。
 \overrightarrow{CD(k)} と垂直な向きに円があるので、どこでもよいから円の端を Rとすれば、
3点 C, D(k), Rを頂点とする三角形は直角三角形であることが分かる。
この直角三角形の辺 CRは、視円錐の母線であるから角 Cは視野角の半分の角度を持つ。
よって、半径 rは、 |\overrightarrow{CD(k)}| \tan(\frac{視野角}{2}) = k \tan(\frac{視野角}{2})であることが分かる。
(例えば、今回の場合は、視野角が60度なので、
 \frac{\sqrt{3}k}{3}となる。)
 Pがこの円の内部にあるとするならば、
 |\overrightarrow{DP}|\lt k \tan(\frac{視野角}{2})…①
のはずである(円のベクトル方程式)。
そして \overrightarrow{DP}・\overrightarrow{CT} = 0…②である。
今、 Dを消してしまおう。
もし Dを活かしたまま回答を得ようものなら、答えるときに Dとは何なのかを言葉で説明しなくてはならないが、それはあくまでも最終手段。できることなら問題に与えられた点だけを使って答えたいのである。

図から明らかに \overrightarrow{OD}=k\overrightarrow{CT}+\overrightarrow{OC}である。

①は |\overrightarrow{OP}-k\overrightarrow{CT}-\overrightarrow{OC}|\lt k \tan(\frac{視野角}{2})
②は
 (\overrightarrow{OP}-k\overrightarrow{CT}-\overrightarrow{OC})・\overrightarrow{CT}=0
 \overrightarrow{OP}・\overrightarrow{CT}-k|\overrightarrow{CT}|^2-\overrightarrow{OC}・\overrightarrow{CT}=0
 \overrightarrow{OP}・\overrightarrow{CT}-k-\overrightarrow{OC}・\overrightarrow{CT}=0
 k=\overrightarrow{CP}・\overrightarrow{CT}
①へ②を代入すると
 |\overrightarrow{CP}-(\overrightarrow{CP}・\overrightarrow{CT})\overrightarrow{CT}|\lt \overrightarrow{CP}・\overrightarrow{CT} \tan(\frac{視野角}{2})
両辺は明らかに正。2乗すると、
 |\overrightarrow{CP}|^2-2\overrightarrow{CP}(\overrightarrow{CP}・\overrightarrow{CT})\overrightarrow{CT}+|(\overrightarrow{CP}・\overrightarrow{CT})\overrightarrow{CT}|^2 \lt (\overrightarrow{CP}・\overrightarrow{CT})^{2}\tan^{2}(\frac{視野角}{2})
 |\overrightarrow{CP}|^2-2(\overrightarrow{CP}・\overrightarrow{CT})^{2}+(\overrightarrow{CP}・\overrightarrow{CT})^{2}|\overrightarrow{CT}|^2\lt (\overrightarrow{CP}・\overrightarrow{CT})^{2}\tan^{2}(\frac{視野角}{2})
 |\overrightarrow{CP}|^2-2(\overrightarrow{CP}・\overrightarrow{CT})^{2}+(\overrightarrow{CP}・\overrightarrow{CT})^{2}\lt (\overrightarrow{CP}・\overrightarrow{CT})^{2}\tan^{2}(\frac{視野角}{2})
 |\overrightarrow{CP}|^2\lt(1+\tan^{2}(\frac{視野角}{2}))(\overrightarrow{CP}・\overrightarrow{CT})^{2}
 |\overrightarrow{CP}|^2\lt(\frac{1}{\cos^{2}(\frac{視野角}{2})})(\overrightarrow{CP}・\overrightarrow{CT})^{2}
となる。
但し、 kには正であるという条件が課されていたので、
 |\overrightarrow{CP}|\lt \frac{1}{\cos(\frac{視野角}{2})} (\overrightarrow{CP}・\overrightarrow{CT})
とできる。 よって、具体的な数字を代入すると
 \left|\left(\begin{array}{a}x-1\\y-1\\z-1\end{array}\right)\right| \lt \frac{2\sqrt{3}}{3}  \frac{1}{13} \left(\begin{array}{a}x-1\\y-1\\z-1\end{array}\right) \left(\begin{array}{a}3\\4\\12\end{array}\right)
 
では最後に、この方程式の正当性をmatlabで確認してみよう。
まずは次のようなファイル「view_cone.m」を書く。

function bool = view_cone(x, y, z)
    OP = [x, y, z];
    OC = [1, 1, 1];
    CT_ = [3, 4, 12];
    CT = CT_./norm(CT_);
    CP = OP - OC;
    angle_of_view = pi/3;
    
    bool = (norm(CP) < (1/cos(angle_of_view/2))*dot(CP, CT));

このファイルを保存したら、次のコードを実行する。

hold on;

%視円錐
for x=[0:0.25:10]
    for y =[0:0.25:10]
        for z=[0:0.25:10]
            if(view_cone(x,y,z))
                scatter3(x,y,z);
            end
        end
    end
end

%視心
for k=[0:0.01:10]
    tmp = [1,1,1] + (k/13)*[3,4,12];
    x = tmp(1); y = tmp(2); z = tmp(3);
    scatter3(x,y,z);
end

 
結果、次の図のように得られた。右は、視心を正面にしたものである。 f:id:ec084:20200820070842p:plain