Ho una matrice tridimensionale. Pensalo come un mattone. Ci sono 24 possibili rotazioni di questo mattone (che mantengono i suoi bordi paralleli agli assi delle coordinate). Come posso generare tutti i corrispondenti array tridimensionali?Come ottenere tutte le 24 rotazioni di un array tridimensionale?
risposta
È possibile utilizzare le matrici di rotazione. La rotazione di un array 3D attorno all'asse x significa che l'elemento in posizione (i,j,k)
verrà mappato sulla posizione (i,-k,j)
. Ovviamente, se l'array è 0-indexed, probabilmente devi sostituire -k
con size-1-k
o qualcosa del genere.
Analogamente, rotazione attorno alle mappe asse Y (i,j,k)
a (k,j,-i)
. Queste due rotazioni possono essere rappresentate come matrici. Per la rotazione dell'asse x:
|i'| |1 0 0| |i|
|j'| = |0 0 -1|*|j|
|k'| |0 1 0| |k|
E per la rotazione dell'asse y:
|i'| |0 0 1| |i|
|j'| = |0 1 0|*|j|
|k'| |-1 0 0| |k|
Qualunque rotazione generale può essere descritto come una sequenza di questi due rotazioni. L'applicazione di due rotazioni consecutivamente è solo moltiplicando le matrici 3x3. Quindi, se trovi tutti i possibili prodotti, otterrai 24 matrici (inclusa l'identità), ognuna corrisponde a una rotazione valida del tuo array. È un po 'difficile trovare tutte le possibili moltiplicazioni, perché non commutano.
penso che si può solo forza bruta tutti i prodotti del modulo (A^p)*(B^q)*(A^r)*(B^s)
, dove A e B sono due matrici prima e p,q,r,s
sono i loro poteri, e la gamma da 0 a 3 (exponentiating A o B a 4 li porterà torna alla matrice identità).
In questo modo, è possibile generare tutte e 24 le matrici di rotazione valide e ruotare l'array 3D utilizzando ciascuna di esse, avendo cura di spostare gli indici negativi in modo da non accedere ai limiti.
Un dado (mezza coppia di dadi) è utile per osservare i 24 diversi orientamenti e può suggerire sequenze operative per generarli. Vedrai che una delle sei facce può essere più in alto, e i lati sottostanti possono essere ruotati in quattro diverse direzioni cardinali. Indichiamo due operazioni: “girare” e “rotolo”, dove volta ruota il dado rispetto all'asse z da un cardinale all'altro, e rotolo ruota il dado 90 ° lontano da te, così la faccia esterna diventa la faccia inferiore e la faccia vicina la parte superiore. Queste operazioni possono essere espresse usando matrici di rotazione come menzionato nella risposta di Felipe Lopes, o possono essere espresse come semplici funzioni che quando date (x, y, z) ritornano (-y, x, z) o (x, z, - y), rispettivamente.
In ogni caso, se si posiziona il dado con 1 sulla faccia vicina, 2 a destra e 3 in alto, si scoprirà che la seguente sequenza di passaggi genera i dodici diversi orientamenti con 1, 2 o 3 punti su inizio: RTTTRTTTRTTT. Quindi la sequenza RTR espone 6, 4, 5 dove 1, 2, 3 erano originariamente, e una ripetizione della sequenza RTTTRTTTRTTT genera i dodici orientamenti con 4, 5 o 6 punti in cima. La sequenza menzionata è incorporata nel seguente codice 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
Il razionale per stampare un elenco ordinato di coppie di punti trasformate è duplice: (i) qualsiasi orientamento faccia può essere specificato dalle posizioni di due dei suoi angoli; (ii) è quindi facile verificare l'univocità di ciascuna coppia, ad es. mediante uscita delle tubazioni a uniq
.
Ecco come inizia l'output ordinato:
((-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))
si dovrebbe fare un tentativo da soli ... –
@ MitchWheat- Questo è un problema difficile! Penso che mi sarei bloccato abbastanza velocemente anche se avessi dato uno sforzo. – templatetypedef