私は3次元配列を持っています。それをレンガと考えてください。このブリックには 24 の可能な回転があります (エッジを座標軸に平行に保ちます)。対応するすべての 3 次元配列を生成するにはどうすればよいですか?
5 に答える
ダイス (ダイスの半分のペア) は、24 の異なる方向を観察するのに便利であり、それらを生成するための操作シーケンスを提案できます。6 つの面のいずれかが一番上にあり、下の面が 4 つの異なる基本方向に回転できることがわかります。「<em>turn」と「<em>roll」の 2 つの操作を示します。ここで、turnは、ある枢機卿から次の枢機卿へと z 軸を中心にサイコロを回転させ、 rollはダイスを自分から 90°回転させます。面が下面、近面が上面になります。これらの操作は、Felipe Lopes の回答で述べられているように回転行列を使用して表現できます。または、(x,y,z) を指定すると (-y,x,z) または (x,z,- y)、それぞれ。
とにかく、サイコロを手前に 1、右に 2、上に 3 で配置すると、次の一連の手順で 1、2、または 3 つのスポットが上にある 12 の異なる方向が生成されることがわかります: RTTTRTTTRTTT. 次に、シーケンス RTR は、元は 1、2、3 だった場所に 6、4、5 を表示し、シーケンス RTTTRTTTRTTT の繰り返しにより、4、5、または 6 つのスポットが上にある 12 の方向が生成されます。上記のシーケンスは、次の python コードに埋め込まれています。
def roll(v): return (v[0],v[2],-v[1])
def turn(v): return (-v[1],v[0],v[2])
def sequence (v):
for cycle in range(2):
for step in range(3): # Yield RTTT 3 times
v = roll(v)
yield(v) # Yield R
for i in range(3): # Yield TTT
v = turn(v)
yield(v)
v = roll(turn(roll(v))) # Do RTR
p = sequence(( 1, 1, 1))
q = sequence((-1,-1, 1))
for i in sorted(zip(p,q)):
print i
変換されたポイントのペアのソートされたリストを出力する理由は 2 つあります。(i) 任意の面の向きは、2 つの角の位置によって指定できます。(ii) 次に、出力を にパイプすることにより、各ペアの一意性を簡単にチェックできuniq
ます。
ソートされた出力の開始方法は次のとおりです。
((-1, -1, -1), (-1, 1, 1))
((-1, -1, -1), (1, -1, 1))
((-1, -1, -1), (1, 1, -1))
((-1, -1, 1), (-1, 1, -1))
((-1, -1, 1), (1, -1, -1))
((-1, -1, 1), (1, 1, 1))
((-1, 1, -1), (-1, -1, 1))
((-1, 1, -1), (1, -1, -1))
((-1, 1, -1), (1, 1, 1))
X が X 軸を中心に 90 度回転し、Y が Y 軸を中心に 90 度回転すると、24 通りの一意の組み合わせが考えられます (5 回転までのすべての可能な組み合わせが与えられます)。 XYYYY など):
1. I
2. X
3. Y
4. XX = YXXY
5. XY
6. YX
7. YY = XYYX
8. XXX = XYXXY = YXXYX = YXYXY = YYXYY
9. XXY = YXXYY = YYYXX
10. XYX = YXY
11. XYY = XXYYX = YYXXX
12. YXX = XXYYY = YYXXY
13. YYX = XXXYY = XYYXX
14. YYY = XXYXX = XYXYX = XYYXY = YXYYX
15. XXXY
16. XXYX = XYXY = YXYY
17. XXYY = YYXX
18. XYXX = YXYX = YYXY
19. XYYY
20. YXXX
21. YYYX
22. XXXYX = XXYXY = XYXYY = YXYYY
23. XYXXX = YXYXX = YYXYX = YYYXY
24. XYYYX = YXXXY
もちろん、X と Y の代わりに任意の 2 つの 90 度回転を使用できます。たとえば、Y と Z です。
または、Z 軸を中心に 90 度回転する Z も使用する場合は、4 回転で十分です。
1. I
2. X = YXZ
3. Y = ZYX
4. Z = XZY
5. XX = XYXZ = YXXY = YXYZ = YXZX = YYZZ = YZXZ = ZXXZ = ZZYY
6. XY = YZ = ZX = XZYX = YXZY = ZYXZ
7. XZ = XXZY = YXZZ = YYYX = ZYYY
8. YX = XZZZ = YYXZ = ZYXX = ZZZY
9. YY = XXZZ = XYYX = YZYX = ZXYX = ZYXY = ZYYZ = ZYZX = ZZXX
10. ZY = XXXZ = XZYY = YXXX = ZZYX
11. ZZ = XXYY = XYZY = XZXY = XZYZ = XZZX = YYXX = YZZY = ZXZY
12. XXX
13. XXY = XYZ = XZX = YZZ = ZXZ
14. XXZ = ZYY
15. XYX = YXY = YYZ = YZX = ZXX
16. XYY = YZY = ZXY = ZYZ = ZZX
17. XZZ = YYX
18. YXX = ZZY
19. YYY
20. ZZZ
21. XXXY = XXYZ = XXZX = XYZZ = XZXZ = YZZZ = ZXZZ = ZYYX
22. XXYX = XYXY = XYYZ = XYZX = XZXX = YXYY = YYZY = YZXY = YZYZ = YZZX = ZXXY = ZXYZ = ZXZX = ZYZZ = ZZXZ
23. XYXX = XZZY = YXYX = YYXY = YYYZ = YYZX = YZXX = ZXXX
24. XYYY = YXXZ = YZYY = ZXYY = ZYZY = ZZXY = ZZYZ = ZZZX
これらの 24 の行列はすべて、それぞれが 2 つのゼロとマイナス 1 またはプラス 1 からなる 3 つの列ベクトルから構成されています。すべての行には、正確に 2 つのゼロもあります。そのため、それらは簡単に生成できます。最初の列ベクトルには 6 つの可能性 ((1,0,0)、(-1,0,0)、(0,-1,0)、(0,1,0) があります。 、(0,0,-1) および (0,0,1))、これは、正の X 軸を正または負の x、y、または z 軸に移動することに対応します。2 番目の列ベクトルには 4 つの可能性しかありません。これは、最初の列がゼロ以外の値を持つゼロを含む必要があるためです。最後に、3 番目の列ベクトルには、プラスまたはマイナスの 1 を配置できる場所が 1 つだけ残っています。これにより、6 * 4 * 2 = 48 のマトリックスが得られますが、それらの半分はオリジナルをミラーリングします (ミラーリングとオプションで回転を組み合わせたものです)。したがって、純粋な回転は 24 個だけです。
回転行列を使用できます。x 軸を中心に 3D 配列を回転させることは、 position の要素が position(i,j,k)
にマップされることを意味し(i,-k,j)
ます。もちろん、配列のインデックスが 0 の場合は、おそらくまたはそのようなもの-k
に置き換える必要があります。size-1-k
同様に、y 軸を中心に回転すると にマップ(i,j,k)
され(k,j,-i)
ます。これら 2 つの回転は行列として表すことができます。x 軸回転の場合:
|i'| |1 0 0| |i|
|j'| = |0 0 -1|*|j|
|k'| |0 1 0| |k|
y 軸の回転については、次のようになります。
|i'| |0 0 1| |i|
|j'| = |0 1 0|*|j|
|k'| |-1 0 0| |k|
一般的なローテーションは、これら 2 つのローテーションのシーケンスとして記述できます。2 つの回転を連続して適用することは、単に 3x3 行列を乗算することです。したがって、それらのすべての可能な積を見つけると、24 個の行列 (ID を含む) が得られ、それぞれが配列の有効な回転に対応します。可能な乗算をすべて見つけるのは少し難しいです。
(A^p)*(B^q)*(A^r)*(B^s)
A と B は前の 2 つの行列でありp,q,r,s
、それらの累乗であり、範囲は 0 から 3 です (A または B を 4 にべき乗すると、恒等行列に戻ります) 。.
このようにすると、24 個の有効な回転行列をすべて生成し、それらのそれぞれを使用して 3D 配列を回転させ、範囲外にアクセスしないように負のインデックスをシフトするように注意することができます。