Aを3D座標x、y、zを持つポイントとし、それらを2D座標x、yに変換したいとします。投影は、与えられた法線によって定義される平面上で直交します。法線が実際に軸の1つである単純なケースでは、座標を削除するだけで簡単に解決できますが、発生する可能性が高い他のケースはどうですか?
ターゲットポイントがある場合[〜#〜] p [〜#〜]座標r_P = (x,y,z)
で、通常のn=(nx,ny,nz)
の平面で、Originを定義する必要があります平面、およびx
およびy
の2つの直交方向。たとえば、Originがr_O = (ox, oy, oz)
にあり、平面内の2つの座標軸がe_1 = (ex_1,ey_1,ez_1)
、e_2 = (ex_2,ey_2,ez_2)
で定義されている場合、直交性はDot(n,e_1)=0
、Dot(n,e_2)=0
、Dot(e_1,e_2)=0
(ベクトルドット積)。すべての方向ベクトルshouldは正規化されていることに注意してください(大きさは1でなければなりません)。
ターゲットポイント[〜#〜] p [〜#〜]は、方程式に従う必要があります。
r_P = r_O + t_1*e_1 + t_2*e_2 + s*n
ここで、t_1
およびt_2
は、e_1
およびe_2
およびs
に沿った2D座標で、平面と点の間の通常の分離(距離)です。
投影によってスカラーが見つかります:
s = Dot(n, r_P-r_O)
t_1 = Dot(e_1, r_P-r_O)
t_2 = Dot(e_2, r_P-r_O)
平面Origin r_O = (-1,3,1)
と法線の例:
n = r_O/|r_O| = (-1/√11, 3/√11, 1/√11)
たとえば、2D座標の直交方向を選択する必要があります。
e_1 = (1/√2, 0 ,1/√2)
e_2 = (-3/√22, -2/√22, 3/√22)
Dot(n,e_1) = 0
およびDot(n,e_2) = 0
およびDot(e_1, e_2) = 0
など。
ポイントの2D座標[〜#〜] p [〜#〜]r_P=(1,7,-3)
は次のとおりです。
t_1 = Dot(e_1, r_P-r_O) = ( 1/√2,0,1/√2)·( (1,7,-3)-(-1,3,1) ) = -√2
t_2 = Dot(e_2, r_P-r_O) = (-3/√22, -2/√22, 3/√22)·( (1,7,-3)-(-1,3,1) ) = -26/√22
面外分離:
s = Dot(n, r_P-r_O) = 6/√11
A
の法線方向への射影を見つける 。次に、その投影をA
から減算します。残っているのは、A
の直交平面への投影です。
ユニットの法線方向n
へのAの射影は、次の式で与えられます。
_(A · n) n
_
A = (x, y, z)
で、法線の単位がn = (nx, ny, nz)
で与えられる場合、n
へのAの射影は
_(x*nx + y*ny + z*nz) n
_
したがって、直交平面へのAの投影は
_A - (A · n) n
= (x, y, z) - (x*nx + y*ny + z*nz) (nx, ny, nz)
_
たとえば、A =(1,2,3)で、nが方向(4,5,6)の法線単位である場合、
_In [12]: A
Out[12]: array([1, 2, 3])
In [17]: d
Out[17]: array([4, 5, 6])
In [20]: n = d/sqrt(4*4 + 5*5 + 6*6) # make n a unit vector
In [13]: n
Out[13]: array([ 0.45584231, 0.56980288, 0.68376346])
_
したがって、直交平面へのAの投影は
_In [15]: A - np.dot(A,n)*n
Out[15]: array([-0.66233766, -0.07792208, 0.50649351])
_
2D座標を見つける方法:
直交平面上に2D座標系を定義する必要があります。つまり、_x-axis
_と_y-axis
_の場所を定義する必要があります。たとえば、(上記の計算を使用して)_x-axis
_を(1,0,0)の直交平面への射影になるように定義できます。これは、(1,0,0)が平面に垂直である縮退した場合を除いて機能します。
x
およびy
軸方向の単位ベクトルを作成したら、A
およびx
にy
を直接投影できます。これらのベクトルの大きさは2D座標です。
たとえば、これは平面への(1,0,0)の投影です。これをx軸方向とします。
_In [42]: x = np.array([1,0,0])
In [45]: x = x - np.dot(x, n) * n
In [52]: x /= sqrt((x**2).sum()) # make x a unit vector
In [53]: x
Out[53]: array([ 0.89006056, -0.29182313, -0.35018776])
_
ここで、y軸方向を計算します。_y-axis
_方向は、法線方向n
とx
の両方に垂直でなければなりません。したがって、y
を 外積 のn
とx
に定義できます。
_In [68]: y = np.cross(n, x)
In [69]: y
Out[69]: array([ -2.77555756e-17, 7.68221280e-01, -6.40184400e-01])
_
平面内のA
の座標は次のとおりです。
_In [70]: np.dot(A, x), np.dot(A, y)
Out[70]: (-0.74414898890755965, -0.38411063979868798)
_