追従カメラは引き算のたまもの。引き算のことをもっと知りたい

この追従カメラは特殊な訓練を受けているため、キャプチャー画像に映ります

はじめまして、バーチャルキャスト クライアント開発のNumAniです。今回のブログではバーチャルキャストにゆかりのある技術について語る機会を設けていただきました。よろしくお願いいたします。

さて、バーチャルキャストをインストールすると、最初から使えるアイテムの中に「追従カメラ」があります。追従カメラとは、常に演者の方を向き続けるカメラです。演者の方を向き続ける……ということは、演者への方向を常に認識しているはずですが、一体どのように認識しているのでしょうか?

私たち人間なら、辺りを軽く見回して、一瞬で演者を見つけることができれば、常にそちらの方向を向くことができるでしょう。 一方で、追従カメラの振る舞いはただのプログラムであり、数値で表される事柄しか認識することができません。 これは私たち人間の感覚からすれば、目と耳をふさいだ状態で、自分の座標と目標の座標だけが知らされて、 そこから自分の向くべき方向を割り出すようなものです (それって学校でやる数学のテストと同じですね)。

そして実際のところ、自分の座標と目標の座標を知っているならば、そこから自分の向くべき方向を計算することは可能です。 今回はベクトルの引き算を使って、追従カメラが向くべき方向を計算してみましょう。

……というのは建前で、今回私がこの記事を書くのは、数学の複雑そうに見える部分が実際にはどれだけ単純なものなのかを知っていただくためなので、追従カメラとは関係ないけれど興味深い話題もいくつかお話ししますよ。キーワードはとにかく引き算です!

前提知識

  • 足し算と引き算の知識
  • 「座標」や「ベクトル」について聞いたことがある程度の知識があると分かりやすいと思います

目標

追従カメラの座標と演者の座標を元に、追従カメラが向くべき方向を計算する方法について考えてみます。 その過程で、以下のことについて解説していきます。

  • ベクトルとはなにか
  • ベクトルの引き算はどんな意味なのか
  • 普通の数の引き算についてもっと考える
  • 負の数の引き算について考える

座標の引き算

座標という考え方をご存じの方も多いと思います。 例えば2D空間ならば、横・縦といった2つの方向が存在します。 その2つの方向にどれだけ進んでいるかを数字で表すのが座標の考え方です。 例えば次のように座標を書いたならば……

(3m, 4m)

これは横に3m, 縦に4m進んだ座標のことですね。

バーチャルキャストの空間は3D空間ですが、今回はより単純な2D空間について話すことにして、

  • 横のことをX座標
    • そして、正の数なら右方向で、負の数なら左方向
  • 縦のことをY座標
    • そして、正の数なら上方向で、負の数なら下方向

と呼ぶことにしましょう。

今回の問題では、追従カメラの座標と、演者の座標が与えられます。 例えば、次のような値だったとしましょう。

  • 追従カメラ: (1m, 3m)
  • 演者: (5m, 5m)

実は、ここから「追従カメラから演者への方向」を計算するには、引き算を使います。演者のX座標から追従カメラのX座標を引き、演者のY座標から追従カメラのY座標を引き、それを新たな座標(のようなもの)のXとYの値として扱うのです。やってみましょう:

この計算で得られた (4, 2) という"座標どうしの差"は、 「右方向に4m、上方向に2m伸びた矢印の向きが、欲しかった方向を差している」 ということを意味しています。

なぜこうなるのかが今回の記事の本題なので、この後解説しますね。

ベクトル

(4, 2) という「座標どうしの差」のことをなんと呼べばよいのでしょうか。 先ほどお話しした通り、この"量"は"向き"を持っていて、その向きが追従カメラの向きとなるわけですが、 この"量"の持つ意味についてよく理解したいところです。

数学の世界には、「座標」と「座標同士の差」を同様に扱える仕組みがあります。それがベクトルです。 追従カメラの座標 (1, 3) も、引き算の結果 (4, 2) も、同じベクトルと呼んでよくて、同じもののように計算で扱ってよいのです。

これは、普通の数の引き算と同じ性質になるようになっています。 普通の数の引き算の例として、たとえば……

Aさんは3個のリンゴを持っていて、Bさんは5個のリンゴを持っているとします。 すると、Aさんから見ると、Bさんは2個多くリンゴを持っていることが分かります。 なぜなら、 5 - 3 = 2 だからですね。 この引き算の式では、 532 はどれも同じ"数"です。

つまり、普通の数とベクトルは、以下の点で似ています:

  • 「リンゴの数5」も「リンゴの数の差2」も同じ"数"として扱える
    • 「2個のリンゴを持っている人」は存在しないが、それと関係なく扱える。
  • 「座標(1, 3)」も「座標同士の差(4, 2)」も同じ"ベクトル"として扱える
    • (4, 2)の座標に位置する物体」は存在しないが、それと関係なく扱える。

ベクトルは、「長さ」と「向き」を持ちます。 たとえば (4, 2) は、座標 (0, 0) の位置から 右に4、上に2 進んだ位置までを 矢印で結んだ場合の、その矢印の長さと向きを表すことができます。

同時に (4, 2) は、座標 (1, 3) の位置から 右に4、上に2 進んだ位置までの 矢印を表すこともできます。 ベクトル表記には、「どこが起点なのか」を表現する能力がありません。 そしてそれは時として、どこが起点なのかを自由に考えることができるということでもあります。

そして、あるベクトルを座標 (0, 0) を起点として考えたとしたら、 そのベクトル自体が座標であることと変わりありませんから、 そのベクトルを「位置ベクトル」と呼びます。座標とは、位置ベクトルのことだったのですね。

ベクトルの引き算

そんなベクトル同士で引き算をするとどうなるのでしょうか?

追従カメラの座標 a = (1, 3) と、 演者の座標 b = (5, 5) を、起点が (0, 0) のベクトル(=位置ベクトル)として描いてみましょう。その差は b - a = (4, 2) でしたね。

するとベクトル (4, 2) が、ベクトルaの先端からベクトルbの先端までをつなぐベクトルとして現れます。 ベクトルの引き算は、「ある座標から見た、ある別の座標までの距離と方向」を計算する方法なのです。

ベクトルの引き算は普通の引き算とは違う?

ベクトルではない普通の数、たとえば 11002.5などは、ベクトルと区別するためにスカラーと呼ばれています。

ベクトルの引き算で用いる、「ある座標からみた別の座標」という考え方は、スカラーの引き算とはかけ離れているような印象を受けるかもしれません。 でも、ベクトルの引き算とスカラーの引き算は、とてもよく似ているのです。

スカラーの引き算の例を出してみましょう。 Aさんは3個のリンゴを持っていて、Bさんは5個のリンゴを持っているとします。 ここで、式 5 - 3 = 2 は、何を意味しているでしょうか?

答えの 2 は、「Aさんから見てBさんがどれだけ多くリンゴを持っているのか」を表しています。 これもまた、スカラーの引き算とベクトルの引き算が似ている点なのです:

  • スカラーの引き算の答えは、「ある量から見て、もう一方の量がどれだけ多いか」
  • ベクトルの引き算の答えは、「ある座標から見て、もう一方の座標のほうがどれだけ進んでいるか」

数直線上にスカラーを置いてみると、ベクトルとスカラーがどれだけ似ているかが分かりやすいです。

5 は、 0 から見て5だけ多い数ですね。3 は、 0 から見て3だけ多い数です。 そう考えると、5は「0から5までをつなぐ矢印」、3は「0から3までをつなぐ矢印」として書けます。

するとこの時、3の先端から5の先端までを矢印つなぐと、その矢印の長さは2になります。 つまり、スカラーの引き算とベクトルの引き算は以下の点でも似ています:

  • 数直線上で、ある数からもう一方の数を矢印でつなぐと、その長さが2つの数の差となる
  • 座標平面上で、あるベクトルの先端からもう一方のベクトルの先端を矢印でつなぐと、その長さが2つのベクトルの差となる

なんだか、スカラーは「1次元のベクトル」のようにも思えますね。 数学の世界は一見関係のない事柄が、実際には密接に関係していることがあります。 こういうところが、数学の美しさと面白さのひとつだと感じます。

負の数の引き算

スカラーの引き算についてもう少し理解を進めてみましょう。 「ある量から見て、もう一方の量がどれだけ多いか」という考え方にのっとると、 負の数の引き算をより具体的にイメージすることができます。

今日、東京の気温は28度だとします。 一方で南極大陸の気温はマイナス48度だとします。 南極大陸の気温から見て、東京の気温は何度高いでしょうか?

これは以下のような式になるはずですね。でも、負の数にあまり詳しくない段階では、この式は少し困ったものです。負の数が「引く方」の数の場合、引き算の答えはどうなってしまうのでしょうか。

28 - (-48) = (答え)

この式は結果的に、

28 + 48 = 76

という風に足し算に変えて計算することになるわけですが、 なぜ負の数で減算をすると加算と同じになるのかについては、考える価値があります。

この引き算は、「ある量から見て、もう一方の量がどれだけ多いか」という発想で式を立てていますから、 今までと同じように、数直線上に矢印を書いてみるとよいかもしれません。

0から28までは、右向きの矢印になります。 一方で、0から(-48)までは、左向きの矢印になりますね。 28 - (-48) の答えは、(-48)の先端から28の先端までを矢印でつないだ長さと同じはずです。

こうして図を書いてみると、(-48)の先端から28の先端へ行くには、0を経由するようです。 こうすると、以下のように考えることができそうです:

(-48の先端から0までの矢印) + (0から28の先端までの矢印) = (-48の先端から28の先端までの矢印)

「-48の先端から0までの矢印」も、「0から28の先端までの矢印」も、簡単にイメージできます。 0から28までの矢印は、右方向に28の長さがあるはずです。 -48から0までの矢印は、右方向に48の長さがあるはずです。

この2つを合成すると、2つの矢印は同じ向きですから、一方の矢印の先端にもう一方の矢印をくっつけて…… 長さ76の右向きの矢印が完成するわけです(これはベクトルの足し算です)。「-48から見て、28は76だけ大きい」ことが分かったので、これが今回の答えです。

(-48)という数をどのような負の数に変えても、正の数へ向かうときは必ず0を経由することに注意してみてください。どんな負の数も、他の数から減算するときは加算に変わってしまうことがイメージできるかと思います。

まとめ

  • ある座標から別の座標への向きは、「ベクトルの引き算」で求められる!
  • ベクトルの引き算は「ある座標から見て他の座標がどれだけ進んでいるか」を求める
  • 普通の数の引き算も、「ある量から見て他の量がどれだけ大きいか」を求める
  • 負の数の引き算も、「ある量から見て他の量がどれだけ大きいか」で考えると簡単にイメージできる

実のところ、追従カメラの向くべき方向を計算するには、ベクトルの引き算をした後にその結果のベクトルの角度をしっかり調べないといけないのですが、そこを理解するにはクオータニオン(四元数)という複雑な概念が立ちはだかっているので、本記事ではこの辺までにしておこうと思います。

今回は「引き算とは何なのか」を中心にお話しさせていただきました。 バーチャルキャストのようなデジタルコンテンツの開発には、ベクトルの知識は必要不可欠なものです。今回お話しした「ベクトルの引き算」はベクトルの世界のほんの一部ですが、本記事を通して皆さんが少しでも数と仲良くなれていれば幸いです!