A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Tutoriais e Programação

Java - Os segredos do copyArea

Sex

10

Abr

2009


20:57

(1 voto de 5.00) 


Nível intermediário

A maior desvantagem da Java é ser lenta. Na verdade, por ser uma linguagem interpretada, é surpreendente não ser maaaiiiis lenta do que é. Claro que compiladores just-in-time e otimizações fazem uma grande diferença. Apesar disto, não há como negar que a velocidade continua sendo algo frustrante.

Por outro lado, se programar fosse um mar de rosas, qual seria a graça? E é possível fazer milagres quando se explora um pouco mais as possibilidades que a linguagem oferece antes de se sentar e começar a teclar, teclar e teclar para programar.

Surpresas da Java

Vejamos o método copyArea da classe Graphics. À primeira vista, uma instrução muito sem graça. Tudo o que ela faz é pegar um retângulo de pixéis de uma parte de uma imagem e copiá-los para algum outro lugar. Grande coisa... nada de tecnologia de ponta, etc e tal.

Explorando mais, constatamos que copyArea é a implementação de uma função gráfica muito básica chamada "Bit Block Transfer". Como a maioria dos métodos gráficos da Java, o copyArea não é escrito em bytecodes Java puros, pois seria muito lento. Na realidade, ele usa a técnica "peer" para executar código nativo sempre que requisitado. Você pode pensar que isto é uma falha do tão propalado "escreva uma vez - execute em qualquer máquina", mas não é. As bibliotecas peer fazem parte da Máquina Virtual Java e mantêm a portabilidade.

Como o copyArea usa código nativo, sua execução é consideravelmente mais rápida do que qualquer coisa escrita em Java pura. Melhor ainda: na maioria das plataformas, este método nem mesmo executa o código normal do processador (CPU) - ele é implementado no hardware! É o sonho de qualquer programador pois, quando as coisas acontecem no hardware, tiram pleno proveito dos circuitos especializados e liberam a CPU para fazer qualquer outra coisa que dela se exija.

Bem, apesar de todas estas considerações, recortar quadradrinhos de imagens continua parecendo uma coisa sem muita utilidade. Se você continua pensando assim, dê uma olhada no applet a seguir:

Espelhando uma imagem

O espelhamento de uma imagem, tanto na horizontal quanto na vertical, é muito fácil de ser obtida. Imagine uma imagem de 10 x 10 pixels. Se quisermos espelhá-la na horizontal, basta criar uma imagem de 20 x 10 pixels (o dobro da largura). Depois, usando copyArea(), copiamos a 1a. coluna para a 20a., a 2a. para a 19a., e assim sucessivamente. Para espelhá-la na vertical, dobramos a altura (10 x 20) e copiamos a 1a. linha para a 20a., a 2a. para a 19a., etc.

Há um truque se quisermos manter o tamanho da imagem. Criamos uma imagem com uma coluna adicional, no caso, 11 x 10 pixels. A 11a. primeira coluna servirá de apoio. Copiamos a 1a. coluna para a 11a., a 10a. para a 1a. e a 11a. para a 10a. Repetimos o processo com as colunas seguintes até alcançamos a coluna do meio, no nosso caso quando trabalharmos com a 4a. coluna. Não há a necessidade de copiar a 5a. para a 5a., e as colunas de 6 a 10 já estão atualizadas.

Nos tutoriais seguintes, veja os applets de espelhamento funcionando e os algoritmos utilizados para obter estes efeitos. Estude-os cuidadosamente pois, por incrível que pareça, estes são o "coração" do famoso applet do lago ou da cachoeira, onde a água parece estar se movendo.

Usando o copyArea na rotação de imagens

Rotação é uma transformação de imagem que faz com que ela "rode" numa determinada direção. O pulo do gato para conseguir uma rotação de imagem rápida é o seguinte:

public void rodaX (Graphics g, double roda) { double novo_x; for (int i = 0; i < (h1<<1); i++) { novo_x = ((double)i * -roda) + ((double)h1 * roda); g.copyArea (0, i, ((w1 * 3) >> 1), 1, (int)novo_x, 0); g.drawLine ((int)novo_x, i, 0, i); g.drawLine ((int)novo_x + ((w1 * 3) >> 1), i, (w1 * 3) >> 1, i); } }

h1 representa a altura da imagem e w1 sua largura. O valor roda especifica quanto a imagem vai rodar para um dos lados. As duas chamadas a drawLine garantem que a posição anterior da imagem seja apagada.

Note que não houve necessidade de fazer cálculos com cada um dos pixéis da imagem. Usando copyArea, tombamos uma linha inteira de pixéis de uma só vez. É uma ferramenta eficiente e rápida para rodar ou aplicar imagens de texturas em alguns tipos de projeção 3D.

Reforço de conhecimento

Você encontra em Rotação de Pixels uma explicação detalhada de conceitos e cálculos matemáticos necessários para entender o mecanismo de transposição num sistema de coordenadas. De posse desses conhecimentos fica fácil identificar que h1 corresponde ao eixo y e que a linha novo_x = ((double)i * -roda) + ((double)h1 * roda) usa o valor em radianos do ângulo de rotação (roda) para obter a nova posição dos pixels.

вулкан удачи игровые автоматы бесплатнокупить посуду спбкомпания ооо полигон отзовикполигон оооvsemsmartофициальный никас

Informações adicionais