プロが教える店舗&オフィスのセキュリティ対策術

3次元以上の直交変換(回転)を、2つのベクトルから求める方法。

ユークリッド空間上で、例えば、ある2つのベクトルa,bが、

a = [1,0,0];
b = [0,1,0];

のように与えられたとき、aベクトルをbベクトルへ「視覚的に」重ね合わせる直交変換を探しています。
つまり、
b = Xa
を満たす直交変換(回転行列)Xの求め方を探しています。
私のイメージとしては、3Dのポリゴンで描かれた自動車をマウスでグリグリ回転させるときに、正面を向いた状態から真横に向ける回転になるでしょうか。
無論、求める直交変換が一意に定まらないことは承知しております(ベクトルと垂直な面方向の自由度など)。また、sinやcosを使う方法は存じ上げておりますが、現在研究中のテーマに不適であるため、あえて利用しません。
どうにか、a,bの成分のみで直交変換を求める(または、直交変換の条件を決定する)一般的な方法があればご教授願います。

また、3次元よりも大きな場合に、例えば、

a = [1,0,0,0];
b = [0,1,0,0];

としたときの、aからbへの回転行列は自由度が高いのですが、
b = Xa
を満たす回転行列Xをa,bを用いてどのように求めることができるのでしょうか。

支離滅裂な説明になっているかもしれませんが、もしご存知であればその参考となるURL等をご教授下さい。

A 回答 (7件)

こんにちは。


だいぶ話が煮詰まっているらしいところへぜんぜん違うこと書いてすみません。

aがbに移るような直交変換ということなら、シンプルに、
 ・n個の互いに直交する単位ベクトルの組 ek (k=1,2,…,n) を、そのうち一つがaの向きになるようにとる。
 ・同様に一つがbと同じ向きになるような単位ベクトルの組 e'kをとる。
 ・ekがe'kに移るように表現行列を定める。
というのではダメなんでしょうか。
あとは a, b から ek, e'k を生成する方法さえ決めてやればいいということになると思うんですが。

以下は、aからekを生成する方法の一例です。
(私がテキトーに考えたものなので、もっと効率いい方法があるだろうとは思いますが)

a=[a1,a2,…,an]について、di=√(Σ[j=1~i](aj^2)) (i=1,2,…n) とし、また ai≠0 となる最小のiをmとする。
ek の第i成分 ek[i] のように書くものとすると、

k=1のとき
  ek[i]=ai/dn
k=2のとき
 m>1なら
  ek[i]=-am/dm (i=1)
       0     (i>1)
 m=1なら
  ek[i]=-a2/d2 (i=1)
       a1/d2 (i=2)
       0    (i>2)
k>2のとき
 k≦mなら
  ek[i]=-1 (i=k-1)
       0 (i≠k-1)
 k>mなら
  ek[i]=-ai*ak/(d(k-1)*dk) (i<k)
       d(k-1)/dk      (i=k)
       0            (i>k)

のようにekを定めると、これらは互いに垂直な単位ベクトルで、e1がaの向きになると思います。
たとえば、a=[0, 1, 2, 3]なら、
 e1=[0, 1/√14, 2/√14, 3/√14]
 e2=[-1, 0, 0, 0]
 e3=[0, -2/√5, 1/√5, 0]
 e4=[ 0, -3/√70, -6/√70, √(5/14)]
という具合です。

なお、k=2のときの式は、k>2のときの式と符号が変わるかどうかの違いしかありません。
これを別扱いにしたのは、a, b から作ったek, e'kが鏡像になることがないようにするためなのですが、
その必要がないなら、k=2のときもk>2のときのときと同じ式でいいと思います。

この回答への補足

>だいぶ話が煮詰まっているらしいところへぜんぜん違うこと書いてすみません。
とんでもございません!回答ありがとうございます。

回答者様のご提案は、先ほどの回答者様のご提案とほぼ同じ考え方と捉えてよろしいでしょうか。

(以下引用)
 ・n個の互いに直交する単位ベクトルの組 ek (k=1,2,…,n) を、そのうち一つがaの向きになるようにとる。
 ・同様に一つがbと同じ向きになるような単位ベクトルの組 e'kをとる。
 ・ekがe'kに移るように表現行列を定める。
(以上引用)

ekが単位ベクトルの組ということで、行列eで表すこととして、
直感的には、eとe'の各ベクトルを一対一に対応する必要がありますよね。
また、「eのうちの一つのベクトルekがaの向きになるようにとる」ことは、任意の組み合わせから一つを選ぶことになり、「e'のうちの一つのベクトルek'がbの向きになるようにとる」ことも同様に、任意の組み合わせから選択することになると思います。
そこで、「e,e'の各単位ベクトルの位置関係を保ったままekをek'」に移すということでしょうか?それとも、位置関係は無視しても結果は同じになるでしょうか。
そのあたりを疑問に思いました。

すみません、ekの生成方ですが、
「ai≠0 となる最小のiをmとする。」
の部分がまだ把握できていないので、検証した上で、また後ほどお礼を差し上げます。

ありがとうございました。

補足日時:2010/09/17 18:34
    • good
    • 0

えぇと, まず「a を b に, b を c に移し『a と b の両方に直交するベクトルはそのまま』」という線形変換 f がただちに直交変換というわけではありません. これが直交変換であるためには, 「a→b, b→c」のところが直交変換である必要があります. 今の場合だと「a, b を含む面内における回転」でしょうか.


で残りの部分ですが, これは #5 の前半とは関係ありません. 後半部分を実行する方法の 1つとして書いたつもり.
そもそも n次元空間における線形変換を規定するには「独立な n本のベクトルがどこに移るのか」がわかれば十分です. #4 や #5 の前半ではこの「独立な n本のベクトル」として「a, b と n-2本の適当なベクトル」を考えていたんですが, これは「その方が計算が簡単かなぁ」と思って書いていただけで, 実際にはそれに限定されるわけではありません.
そこで, #5 の後半では「a とか b とかは無視して, 独立な n本のベクトルがどこに移るのかを考える」という方針に転換しています. 特に, 「独立な n本のベクトル」として「標準正規直交基底をなす n本のベクトル」をもってくれば, これらの移る先を (適切に) ならべるだけで変換を表す行列ができてしまいますから, 「直交補空間の n-2本の独立なベクトルを考えるより簡単」というわけです.
そうすると問題は「a とか b とかを特に意識することなくてきとうに選んだベクトルに対し, 考えている変換による移り先をどう計算すればよいか」ということになります. これについて考えたのが最後のあたり.
あ, 「標準正規直交基底をなす n本のベクトル」というのは, 実際には「どれか 1個の成分だけが 1 であとは全部 0」というやつらです. これなら, 何をどうやっても必ず独立ですよね.

この回答への補足

ありがとうございます。

>えぇと, まず「a を b に, b を c に移し『a と b の両方に直交するベクトルはそのまま』」という線形変換 f がただちに直交変換というわけではありません.

これは、失礼しました(汗
等価というのは余りにも早合点過ぎて、迂闊でした。確かにノルムに関する言及などは一切無いですね・・・。


#5の話の流れは把握しました。

>特に, 「独立な n本のベクトル」として「標準正規直交基底をなす n本のベクトル」をもってくれば, これらの移る先を (適切に) ならべるだけで変換を表す行列ができてしまいます

了解しました。#5で述べられたベクトルxが正規直交基底を表していたのですね。
ただ、正規直交基底の移り先を計算する手順としては、次元数をnとして、

1.全ての標準正規直交基底を、与えられた2ベクトルとその直交補空間上のn-2本の独立なベクトルを用いて表す。

2.条件式を立て、「直交補空間上のn-2本の独立なベクトル」を全て求める。

3.標準正規直交基底の移り先が計算できるので、計算する。

4.移る前と移った後から、変換行列を求める。

ということでしょうか。

補足日時:2010/09/17 10:12
    • good
    • 0
この回答へのお礼

夜遅くから、ありがとうございます。
お礼が遅れて申し訳ありません。


回答者様の今回の解説で、具体的なアルゴリズムが見えてきました。

本当に、本当に助かりました。

ありがとうございます。

お礼日時:2010/09/17 10:14

あ~はい, その通りです.


「a と b の両方に直交するベクトルの集合」はベクトル空間 (直交補空間) をなし, その次元は n-2 です. この直交補空間から n-2本の独立なベクトルを選べば... いい....
あれ? なんかおかしいなぁ. ん~....
ぐはっ. もっとかんたんじゃね~か.
「標準正規直交基底をなす各ベクトルがどのように移るか」は (少なくとも理論上) 計算で求まるはずだ....
「a を b に, b を c に移し『a と b の両方に直交するベクトルはそのまま』」という線形変換 f をベクトル x = sa + tb + u (s, t は実数で u は a と b の両方に直交する) を移すと, 得られるベクトルは y = f(sa+tb+u) = sb + tc + u. x, a, b が与えられれば s, t, u は当然求まる.

この回答への補足

ご親切に回答いただき、ありがとうございます。


>「a を b に, b を c に移し『a と b の両方に直交するベクトルはそのまま』」という線形変換 f

これは即ち、直交行列と等価であるということになるでしょうか。

>x = sa + tb + u (s, t は実数で u は a と b の両方に直交する) を移すと, 得られるベクトルは y = f(sa+tb+u) = sb + tc + u

ここで定義されたベクトルxは直交補空間上に無いようですね。
線形変換fがaをbに、bをcに、uはそのままにするものなら、線形性より、
f(sa+tb+u) = sb + tc +u
となりますね。
>x, a, b が与えられれば s, t, u は当然求まる
確かにs,tは求まりますが、uは「a,bと直交する任意のベクトル」という定義であり、また、xはランダムに定めるなどをしたところで、高次元では唯一に定める(求める)ことは出来ないのでは無いでしょうか。

一応、私としては直交補空間から適当なベクトルを選択(ランダムとか)してもかまわない問題を扱っているので、大変参考になりました。
ありがとうございます。

補足日時:2010/09/16 13:36
    • good
    • 0
この回答へのお礼

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

突き詰めたところ、変換を行う行列を直に求めるよりも、私はもっと根本的な部分から学習しなおした方がいいのかもしれません。
私が扱っている問題は、三次元まではいわゆるアフィン変換で解決可能だったのですが、次元を拡張する必要に迫られてしまったため、今回、質問いたしました。
あと少し、皆様からの情報をお待ちしたいと存じます。

ありがとうございました。

お礼日時:2010/09/16 13:54

#3 の線でいくと


・a と b を含む平面上では適当な角度の回転
・その平面に直交する方向は何も変わらない
ような変換が得られます. そして, これを決めるためには「a と b の両方に直交するベクトル」として独立な n-2 本を使えばどんなものでも構いません. 何を使っても結果は同一のはずです.
とはいえ, 「独立な n-2 本」をどう選ぶかという問題は残るなぁ. 3次元ならベクトル積を使って自動的に決まるんだが....

この回答への補足

書き込みありがとうございます。

>そして, これを決めるためには「a と b の両方に直交するベクトル」として独立な n-2 本を使えばどんなものでも構いません.

独立な「n-2本」といいますと、「n-2次元」空間上の任意の独立な「n-2本」のベクトルという解釈でよろしいでしょうか?
だとすれば、正にその通りだと思います。

>「独立な n-2 本」をどう選ぶかという問題は残るなぁ

そのベクトルが満たすべき条件はわかるのですが、どのように選ぶか(または生成するか)は確かに問題設定に依存するようですね。問題に合わせていろいろと試してみます。

ありがとうございました。

補足日時:2010/09/15 18:28
    • good
    • 0

「a から b への回転」をすることによって「b が c に移る」ということがわかれば,


b = Xa
c = Xb
です. で, a と b の両方に直交するベクトル u は (回転してもそのままと思って)
u = Xu
なので, これらの式を駆使すれば X が求まるはず.
「a と b の両方を含む面内での回転」ならこんな感じでいかんかなぁ?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
その方法は面白いですね。

ただ、次元数がnのとき、「aとbの両方に直交する(単位?)ベクトルu」の候補がn-2次元空間上に存在することになってしまいますね・・・。

大変参考になりました。ありがとうございます。

お礼日時:2010/09/15 15:18

#1です。


a=[1,0,0,0],b=[0,1,0,0]
a~→b~(X)
単なる写像ではなく、Z軸に回りにπ/2[rad])回転する回転行列なら
Xの2列目~4列目の列行列を順に
[-1,0,0,0]~
[0,0,1,0]~
[0,0,0,1]~
とすれば良いでしょう。
つまり
X=
[[0,1,0,0]~,[-1,0,0,0]~,[0,0,1,0]~,[0,0,0,1]~]
=
[0,-1,0,0]
[1,0,0,0]
[0,0,1,0]
[0,0,0,1]
となります。
任意の座標ベクトルA[x1,x2,x3,x4]をXでπ/2[rad]回転させると
B[y1,y2,y3,y4]に移ったとすれば
B~=XA~=[-x2,x1,x3,x4]~=[y1,y2,y3,y4]~
となります。

参考URL:http://ft-lab.ne.jp/cgi-bin/wiki.cgi?page=%A5%A2 …

この回答への補足

ありがとうございます。
そして、またもや誤解を与えてしまったようですみません。
私の最初の質問を読み返してみると、あたかもa=[1,0,0,0] , b=[0,1,0,0]の場合「のみ」を質問しているようになっていました。私はこのケースの解法を既に存じ上げております。
また、2つのベクトルの偏角を用いる手法ではなく、一般的な成分表示(単位ベクトルが好都合だが、とくにそれと限定しない)で、成分のみを用いて解の候補を求める方法を探しております。

当初の質問文が不適であったようなので、質問を訂正いたします。

a=[a1,a2,a3,a4]^T
b=[b1,b2,b3,b4]^T

の場合に、

b = Xa

を満たす直交行列(回転行列)の解の候補の求め方を教えてください。
また、4次以上の場合も同様に解ける方法を探しております。

恐らく解説が大変長くなると思われるので、参考URL等をご教示いただければ幸いです。

回答者様に誤解を与え、大変失礼致しました。

補足日時:2010/09/15 15:06
    • good
    • 0
この回答へのお礼

参考URLの件、ありがとうございます。

やはりポリゴンを扱うときでも、偏角と三角関数を利用していますね・・・。
このあたりの方法は存じ上げているのですが、「成分のみを用いた解の候補の導出」は大学で学んだ覚えがないのです(汗

ありがとうございました。

お礼日時:2010/09/15 15:32

>a = [1,0,0,0];


>b = [0,1,0,0];
a,bの転置をそれぞれa~,b~とおけば、
a~,b~は列ベクトルになり
b~=Xa~
となります。

>b=Xa
これは間違い。

Xの1列目はb~になります。この1列目の1はaの1番目の成分が1(他の成分は全て0)であるところ
から来ています。
2列目~4列目の要素は任意(自由度12)なので全部0とでもすれば良いでしょう。
X=
[b~,[0],[0],[0]]
ただし、[0]≡[0,0,0,0]~

この回答への補足

すみません。私の質問が曖昧であったため、回答者様へ誤解を与えてしまった模様です。

私は「直交行列による変換」を「直交変換」として述べました。
即ち、回転行列のことです。

よって、回答者様の以下の部分、

>2列目~4列目の要素は任意(自由度12)なので全部0とでもすれば良いでしょう。

ここで述べられた「任意(自由度12)」が、「3×4個の成分は任意の実数でよい」という意味であれば、これは直交変換になり得ないため、不適になります。

回答者様へ誤解を与えてしまいましたことをお詫び申し上げます。

補足日時:2010/09/15 13:19
    • good
    • 0
この回答へのお礼

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

そうですね、[]の表記を用いた場合は転置しなければならないですね。

[]で表現した部分は[]^Tという書き方が適切でした。すみません。

お礼日時:2010/09/15 13:24

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