![書籍転載:KINECT for Windows SDKプログラミング Kinect for Windows v2センサー対応版(7)](https:///re.buildinsider.net/small/bookkinectv2/index/icon.x.png)
書籍転載:KINECT for Windows SDKプログラミング Kinect for Windows v2センサー対応版(7)
空間内のベクトル ― Kinectで学ぶ数学
― Chapter 8 ― 8.2 ―
Kinectではプレイヤーの関節の3次元座標を取得できる。2次元の数学を理解したら、次に3次元空間の数学を理解しよう。
Kinectで必要となる数学を説明します。前回は平面上のベクトルについての数学を解説しました。本稿はその続きとして、空間内のベクトルについて説明します。
書籍転載について
本コーナーは、秀和システム発行の書籍『KINECT for Windows SDKプログラミング Kinect for Windows v2センサー対応版』の中から、特にBuild Insiderの読者に有用だと考えられる項目を編集部が選び、同社の許可を得て転載したものです。
『KINECT for Windows SDKプログラミング Kinect for Windows v2センサー対応版』の詳細や購入は秀和システムのサイトや目次ページをご覧ください。プログラムのダウンロードも、秀和システムのサイトから行えます。
ご注意
本記事は、書籍の内容を改変することなく、そのまま転載したものです。このため用字用語の統一ルールなどはBuild Insiderのそれとは一致しません。あらかじめご了承ください。
■
8.2 空間内のベクトル
8.2.1 3次元ベクトル
いよいよ3次元空間の話に移りますが、実は2次元の場合とそれほど変わりません。
定義7
任意の実数 x1,x2,x3,y1,y2,y3,k に対して、
![(x_1,x_2,x_3)+(y_1,y_2,y_3)=(x_1+y_1,x_2+y_2,x_3+y_3)
k(x_1,x_2,x_3)=(kx_1,kx_2,kx_3)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-57.gif)
という足し算と実数倍ができるような実数2つの組 (x1,x2,x3) や(y1,y2,y3) を3次元ベクトルという。また、(0,0,0) を零ベクトルと呼んで 0 と書く。さらに
![e_1=(1,0,0), e_2=(0,1,0), e_3=(0,0,1)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-58.gif)
を基本ベクトルという。
定義8
ある与えられた3次元ベクトル x,y,z と未知のスカラー s,t,u について
![sx+ty+uz=0](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-59.gif)
が成り立つのが s=t=u=0 に限るとき、ベクトル x,y,z は線型(一次)独立であるという。また、2つの3次元ベクトル x,y について
![sx+ty=0](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-60.gif)
が成立するのが s=t=0 に限るときも同様にベクトル x,yを線型独立であるという。
基本ベクトル e1,e2,e3 はもちろん線型独立ですが、任意の3次元ベクトルが3つのベクトル x,y,z で
![ax+by+cz](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-61.gif)
とただ一通りに表されるための必要十分条件がベクトル x,y,z が線型独立であることです。
定義9
2つのベクトル
![x=(x_1,x_2,x_3), y=(y_1,y_2,y_3)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-62.gif)
に対して、
![x_1 y_1+x_2 y_2+x_3 y_3](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-63.gif)
をベクトル x,y の内積といい、
![x·y](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-64.gif)
と書く。さらに x=(x1,x2,x3) として
![√(x·x)= √(x_1^2+x_2^2+x_3^2)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-65.gif)
をxの長さまたは大きさといい、 |x| で表す。
内積についてベクトル x,y,z、スカラー k に対して
![x·y=y·x
(kx)·y=k(x·y)
x·(y+z)=x·y+x·z](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-66.gif)
が成り立つことも同様です。
定義10
2つのベクトル
![x=(x_1,x_2,x_3),y=(y_1,y_2,y_3)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-67.gif)
に対してベクトル
![(x_2 y_3-x_3 y_2,x_3 y_1-x_1 y_3,x_1 y_2-x_2 y_1)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-68.gif)
をベクトル x,y の外積といい、
![x×y](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-69.gif)
と書く。
外積についてはベクトル x,y,z およびスカラー k について以下が成り立ちます。
![kx×y=x×ky=k(x×y)
x×(y+z)=x×y+x×z
x×y=-y×x
x×x=0](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-70.gif)
特に、x×y=y×x ではないことに注意してください。
8.2.2 3次元ベクトルの幾何的意味
今Kinectのカメラ座標に合わせてKinectに向かって右を x 軸正の向き、鉛直上向きを y 軸正の向き、Kinectに正対して後方を z 軸正の向きとした3次元の直交座標系が定義された空間内にプレイヤーがいると考えます。
![空間内にプレイヤー](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-71.gif)
さらにこのとき下図のように長さ r, 角 θ, φ を 0 < r, 0 ≤ φ ≤ π, -π ≤ θ < π であるようにとると、任意の零ベクトルでないベクトル (x1,x2,x3) は
![(x_1,x_2,x_3)=r(cosθsinφ,cosφ,sinθsinφ)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-72.gif)
と一意に表されます。
![動径/方位角/天頂角](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-73.gif)
r を動径、θ を方位角、φ を天頂角ということがあります。2次元のときと同様に代数的に書けば以下のようになります。
![cosφ=x_2/√(x_1^2+x_2^2+x_3^2),sinφ=√(x_1^2+x_3^2)/√(x_1^2+x_2^2+x_3^2)
cosθ=x_1/√(x_1^2+x_3^2),sinθ=x_33/√(x_1^2+x_3^2)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-74.gif)
したがって、3次元ベクトルは座標空間内の有向線分に対応し、座標空間の原点から各点に引いて得られる有向線分を表すベクトルを位置ベクトルと呼びます。
さて、位置ベクトルが x,y となる点を X,Y とすれば2次元のときと同様 OX,OY,XY の長さを変えず ∆OXY を回転させて ∆OX′Y′ とし、X′,Y′ の位置ベクトル x′,y′ をそれぞれ
![x^'=|x|(1,0,0)
y^'=|y|(cosθ,sinθ,0)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-75.gif)
とすることができ、
![x·y=x^'·y^'=|x||y|cosθ](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-76.gif)
であることがわかります。したがって3次元ベクトルの内積もベクトルの直交性の判定に使えます。
EXERCISE 6
「右ひじ→右手首2次元ベクトルと右ひじ→右肩2次元ベクトルの内積」および「右ひじ→右手首3次元ベクトルと右ひじ→右肩3次元ベクトルの内積」を表示するKinectアプリケーションを作成してください。そしてひじの角度や位置を色々変えて、右ひじ→右手首・右ひじ→右肩ベクトルの、2次元ベクトルとしての直交と3次元ベクトルとしての直交とは必ずしも一致しないことを確認してください。
点 A,B の位置ベクトルをそれぞれ a,bとすると、線分 AB 上の点はパラメータ 0 ≤ t ≤ 1を用いて
![ta+(1-t)b](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-77.gif)
と2次元のときと全く同様に表されます。パラメータ t の範囲制限を外せば直線 AB 上の点を表すことができるのも全く同様です。
点 A,B,C の位置ベクトル a,b,c とすると、パラメータ 0 ≤ s,t ≤ 1を用いて
![ta+sb+(1-t-s)c](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-78.gif)
を考えると、これは三角形 ABC の辺および内部の点を表します。ただし、b-a とc-a が線型従属である(線型独立ではない)ときは、三角形 ABC が潰れてしまって描けませんので注意が必要です。その場合は上の式は線分を表すことになります。逆に、b-a とc-a が線型独立であれば問題なく三角形 ABC を描くことができ、点 A,B,C を通る平面 ABC がただ1つ存在します。そしてその平面 ABC の点は範囲制限を外した実数パラメータ s,tを用いて ta+sb+(1-t-s)c で表せます。さて、ここでベクトル b-a, c-a に直交する方向ベクトル、すなわち
![n·(b-a)=0
n·(c-a)=0](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-79.gif)
が成り立つような方向ベクトル n を考えます(2つあります)。このとき n·a=n·b=n·c
ですから、
![n·{ta+sb+(1-t-s)c-a}=(t+s+1-t-s-1)n·a=0](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-80.gif)
が成り立ちます。したがって、n は平面 ABC 上にある任意のベクトルと直交、すなわち平面 ABC と直交します。このような方向ベクトルを平面 ABC の法線ベクトルといいます。
EXERCISE 7
Kinect SDKのBodyFrame.FloorClipPlaneを用いると、Vector4のWフィールドとして床までの距離(Kinectセンサーの高さ)、X,Y,Z フィールドとして床の法線ベクトルが得られます。これを用いてKinectを設置した位置からプレイヤーが立っている位置までの距離を表示するKinectアプリケーションを作成し、Kinectの角度を変えてもその距離が変わらないことを確認してください。
外積については以下のような性質が知られています。
- x×y は x にも y にも直交しているベクトル
- x,y,x×y は右手系を作る
- |x×y| は x と y を2辺とする平行四辺形の面積に等しい
1. x=(x1,x2,x3), y=(y1,y2,y3) として、x×y と x の内積をとると、
となり、x×y と x が直交していることが分かります。同様にして x×y と y が直交していることも同様にして分かります。したがって、x×y は x にも y にも直交しているベクトルです。
![x×yはxにもyにも直交しているベクトル](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-82.gif)
2. 1. により x×y は x にも y にも直交しているベクトルですが、x にも y にも直交するベクトルというのは図に見るように2方向あります。実際には、実線矢印になっている上方に向かうベクトルが x×y ですが、このように破線矢印方向ではなく実線矢印方向であることを x,y,x×y が右手系を作ると言います。名称の由来は x を右手親指、y を右手人差し指、x×y を右手中指の方向に見ることができるということです。「x から y へ180度以内の角度で回るときに右ネジが進む向きが x×y」だと説明されることもあります。
3. 成分を用いた計算により
![|x|^2 |y|^2=|x·y|^2+|x×y|^2](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-83.gif)
であることが確かめられます。一方ベクトル x とベクトル y との間の角を θ とすれば
![x·y=|x||y|cosθ](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-84.gif)
ですから、
![|x×y|=|x||y||sinθ|](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-85.gif)
であることが分かります。これはすなわち x と y を2辺とする平行四辺形の面積です。
![|y|sinθ](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-86.gif)
EXERCISE 8
右ひじ→右肩ベクトルと右ひじ→右手首ベクトルおよびその外積を矢印や線分で表示するKinectアプリケーションを作成してください。腕を色々動かしてもこれらのベクトルが常に右手系を作っていることを確認してください。
8.2.3 空間内の線型写像
2次元のときと同様、3次元ベクトル全体から3次元ベクトル全体への線型写像 T を考えます。線型写像とは
![T(u_1+u_2)=T(u_1)+T(u_2)
T(ku)=kT(u)](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-87.gif)
という性質を持つ写像のことでした。ベクトルをすべて縦ベクトルとして
とおけば線型写像は
![(■(A_11&A_12&A_13@A_21&A_22&A_23@A_31&A_32&A_33))](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-89.gif)
という行列で表すことができます。すなわち、
が成り立ちます。
EXERCISE 9
行列
![(■(2&-1&1@-2&3&-1@1&-1&0))](https:///re.buildinsider.net/small/bookkinectv2/0802/8-2-91.gif)
を用いて右ひじ-右手首3次元ベクトルを線型変換したベクトルと元の右ひじ-右手首3次元ベクトルを矢印もしくは線分で表示するKinectアプリケーションを作成してください。変換前と変換後の2つのベクトルが同じ向きになる方向が今度は3つありますので探してみてください。
■
次回は、ベクトルの回転について説明します。
※以下では、本稿の前後を合わせて5回分(第5回~第9回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
![書籍転載:KINECT for Windows SDKプログラミング Kinect for Windows v2センサー対応版(7)](https:///re.buildinsider.net/small/bookkinectv2/index/icon.s.png)
5. Kinect WPF ControlsでWPFアプリでもジェスチャーを活用しよう
WPFアプリにKinectを操作するための機能を実装する場合にはKinect WPF Controlsが便利だ。その機能概要を紹介する。