La pequeña aplicación efecto lente, apareció como resultado de una Semana Santa sin planes.
Por aquel entonces estaba terminando de programar la primera versión del encriptador (File Encoder Application), y necesitaba algo vistoso para el Acerca de ...
La idea original no es mía, sino que la implementé siguiendo un efecto que había visto en una de aquellas legendarias demos de DOS.
La forma de implementación escogida, fue encapsular el efecto dentro de un JPanel de Java swing.
Todo lo que se ponga dentro del panel, puede ser "ampliado" con la lupa, que puede ser colocada en las coordendas que se escojan.
Especialmente costoso fue el conseguir que los refrescos de los componentes de texto (en concreto cuando se modifica la ubicación del texto seleccionado), no afectara negativamente al efecto visual.
Internamente, la forma de funcionar es que cuando se crea el LensJPanel, se le pasa el JPanel contenido al que va a hacer el efecto, el radio de la lupa que va a tener, y si va a ser una lupa de apliación o de disminución.
Al tener el radio y si la lupa va a ser de ampliación o disminución, se crea una matriz cuadrada de dos dimensiones, con un elemento por cada pixel del cuadrado que contiene la lupa.
Para cada uno de esos píxeles (pixel destino), calcula las coordenadas de la imagen original (pixel origen) de donde se tendrá que coger el color para cuando se realice la transformación.
La transformación es una sencilla transformación en coordenadas polares. Lo explico para el caso de lente de ampliación:
Para una posición determinada del cuadro de la lente, se calcula un pixel del que se recogera el color cuando se haga la transformación. Ese pixel, estará también dentro del cuadro de la lente. Además, para un pixel determinado, se calcula el radio (desde el centro de la lente), y el ángulo. El pixel "origen" para el pixel que estamos calculando, estará con ese mismo ángulo, pero cambiará el radio. El radio siempre va de 0% a 100% tanto para los píxeles "destino", como para los píxeles "origen", donde 100% es la longitud del radio de la lente. Es decir, para cada pixel destino, para calcular su pixel origen, se mantiene su ángulo, y el radio se transforma, usando una función con derivada monótona creciente, en el intervalo entre 0 y 1, donde f(0) valdrá 0, y f(1) valdrá 1, donde 0 es 0% del radio de la lente y 1 es el 100% del radio de la lente. Eso querrá decir que los radios tomarán su pixel origen de un radio menor, cosa que hará el efecto de que el círculo de la lente, amplía. Fuera del círculo de la lente, la transformación será la identidad (es decir, no variará el píxel origen)
La explicación me ha quedado un poco confusa, pero si te interesa el asunto ponte en contacto conmigo.
Espero que a alguien le sea de utilidad :-)