Já discutimos como podemos representar uma imagem a preto e branco em Python: uma lista de listas. Para resolver este problema sabemos que temos que percorrer toda a imagem e para cada elemento da imagem saber qual será a sua nova posição. Mas no caso de uma rotação de 90 graus isso é fácil de resolver se olharmos globalmente para a matriz que representa a nossa imagem: a coluna i da matriz vai passar a ser a linha i da nova matriz… Daí a solução seguinte:
def roda_90(imagem): """Baseia-se na construção da transposta da imagem vista como uma matriz.""" imagem_aux = list() # troca colunas por linhas = transpõe for coluna in range(len(imagem[0])): nova_linha = list() for linha in imagem: nova_linha.append(linha[coluna]) imagem_aux.append(nova_linha) # inverte dentro das linhas for linha in range(len(imagem_aux)): imagem_aux[linha] = imagem_aux[linha][::-1] return imagem_auxEsta solução numa ideia simples: percorrer por colunas e para cada coluna ir buscar os elementos das diferentes linhas. O modo como fazemos isto obriga-nos no final a inverter todas as linhas. Esta ultima parte não é simpática. Mas podemos mudar as coisas.
def roda_90_b(imagem): """Baseia-se na construção da transposta da imagem vista como uma matriz.""" imagem_aux = list() # troca colunas e linhas = transpõe for coluna in range(len(imagem[0])): nova_linha = list() for linha in imagem: nova_linha = [linha[coluna]] + nova_linha imagem_aux += [nova_linha] return imagem_auxComo se pode ver, em vez de usarmos append, que coloca sempre no final, usamos a operação de concatenação de listas (+), colocando o novo elemento sempre à cabeça, o que permite ter no final a nova linha já invertida.
Como temos vindo a explicar ao longo destes pequenos posts há sempre muitas alternativas. Algumas fazem uso de um conhecimento mais profundo de Python. É o caso da solução que apresentamos a seguir.
def roda_90_c(imagem): copia = copy.deepcopy(imagem) transposta = list(zip(*copia)) final = [linha[::-1] for linha in transposta] return finalNeste exemplo, usamos um argumento na forma *copia. Isto significa que o objecto copia vai ser desmembrado nos seus elementos e é sobre esses elementos que vai ser aplicada a função zip. Deste modo obtemos a transposta. Depois é só inverter cada linha usando listas por compreensão. Refira-se finalmente que usámos uma cópia profunda da imagem inicial para não a destruir.
Sem comentários:
Enviar um comentário