Capturar webcam con VB.NET

¿Que haremos? Crearemos una aplicación en Visual Studio, la cual hará uso de una webcam para capturar el video en frames independientes y depositarlos en memoria para despues mostralos al usuario a través de un picturebox y un Timer para crear la ilusión de movimiento. ¿Porque lo haremos? Porque es justo y necesario ¿Que necesitamos? [...]

Envío de correo con JavaMail/Netbeans

JavaMail es una expansión de Java que facilita el envío y recepción de e-mail desde código java. JavaMail implementa el protocolo SMTP (Simple Mail Transfer Protocol) así como los distintos tipos de conexión con servidores de correo -TLS, SSL, autentificación con usuario y password, etc [Según SantaWikipedia] ¿Qué necesitamos? JavaMail 1.4.5 Java y Netbeans 6.9 [...]

Proyecto de base de datos Firebird VB

En este proyecto realizaremos una aplicación de base de datos Firebird con el lenguaje de programación de Visual Basic de Microsoft, este proyecto tendrá las funciones básicas de gestión INSERT, DELETE, UPDATE y una interfaz de usuario para utilizarlas. ¿Que necesitamos? Visual Studio 2008 o superior Firebird última versión Firebird ADO.NET Data Provider. Conocimientos básicos [...]

Imprimir imagen con Print

La siguiente clase hace uso de PRINT para imprimir una imagen que se encuentra en un variable de tipo FileInputStream, esta clase a su vez es implementada desde una interfaz que hace fácil su uso, la clase así como todo el proyecto esta comentado. import java.io.File; import javax.print.Doc; import java.io.IOException; import javax.print.DocFlavor; import javax.print.SimpleDoc; import java.io.FileInputStream; [...]

Code Army Bolivia

21/8/10

Java2D: Rotación de Figuras

JAN29


Java2D nos permite realizar transformaciones en los objetos que creemos, como ser rotacion, traslación, escalado o una combinacion de todas ellas, ahora realizaremos una aplicacion en netbeans 6.0 para rotar una figura, como la que vemos en la imagen de arriba.

Importante:
En un eje de coordenadas, nosotros expresamos los angulos de derecha a izquierda en sentido contrario a las agujas del reloj, según me acuerdo de la escuela :)
Pero en Java2D, es al reves, los angulos van en el sentido de las agujas del reloj, cosa de locos no. Esto sucede porque java2D toma como eje imaginario la esquina superior izquierda

Proyecto:

1. Creamos un nuevo proyecto en netbeans, dale el nombre que quieras y añade una clase Interfaz, diseña esta interfaz como se ve en la imagen de abajo, no olvides colocar los nombres como se ven abajo

2. Ahora crea una nueva clase, la que llamaremos j2dPanel.java, esta clase se extendera de un JPanel, el codigo que debes ingresar es este:


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.QuadCurve2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
/**
 * @web http://jc-mouse.blogspot.com/
 * @author Mouse
 */
public class j2dPanel extends JPanel{
    double centrox,centroy;
    double rotate; 
    /*constructor*/
    public j2dPanel(Dimension d){
     this.setPreferredSize(d);
     this.setSize(d);
     this.setVisible(true);
     //se obtiene las coordenadas del centro del jpanel
     this.centrox= this.size().width/2;
     this.centroy = this.size().height/2;
     //se inicializa la rotacion en o grados
     rotate = 0;
     this.repaint();     
    }
    
  @Override                   
  public void paintComponent(Graphics g){
    //se inicializa java2d
    super.paintComponent(g);      
    Graphics2D g2 = (Graphics2D)g;  
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    // se añade un color de fondo degrado
    g2.setPaint(new GradientPaint(0, 0, new Color(131,131,131), Float.valueOf(this.getSize().width), 0, new Color(188,194,236)));
    g2.fill(g2.getClip());       
    //se creo otro objeto AffineTransform para guardar los valores iniciales
    AffineTransform oldt = g2.getTransform();        
    //se aplica la rotacion y se traslada las coordenadas para que coincida con el centro del JPanel
    g2.transform(AffineTransform.getRotateInstance(Math.toRadians(rotate),this.centrox,this.centroy));               
    /************************************************************************/
    /* Una ves que se aplica la transformacion , todas las figuras se dibujaran siguiendo
     el angulo asignado en radianes y tomando como eje el centro del JPanel  */
    //grosor y color de pincel      
    g2.setColor(new Color(200,10,10));
    //se dibuja la figura, junto a una linea que nos servira para apreciar mejor la rotacion
    g2.setPaint(new GradientPaint((float) this.centrox-100, (float) this.centroy, new Color(200,0,25), (float) this.centrox+100, (float) this.centroy, new Color(0,96,27)));
    g2.fill(new Rectangle2D.Double( this.centrox-100, this.centroy-50, 200, 100));
    g2.fill(new Rectangle2D.Double( this.centrox-100, this.centroy-50, 100, 170));
    g2.setColor(new Color(0,0,200));
    g2.setStroke(new BasicStroke(4.0f)); 
    g2.draw(new Line2D.Double(this.centrox,this.centroy,this.centrox+100,this.centroy));
    //un poco de texto
    g2.setFont(new Font("Arial", Font.BOLD, 12));
    g2.drawString("  R=" + rotate+"°",(float) this.centrox+100 ,(float) this.centroy);
    /************************************************************************/
     
    //retornamos a los valores iniciales
    g2.setTransform(oldt);
    
    g2.setColor(new Color(0,0,0));
    g2.setFont(new Font("Arial", Font.PLAIN, 12));
    g2.drawString("Rotación (Grados) = " + rotate + "°", 10,25);
    g2.drawString("Rotación (Radianes) = " + Math.toRadians(rotate), 10,50);    
    g2.setFont(new Font("Arial", Font.BOLD, 12));
    g2.drawString("x' 180°", 10 ,(float) this.centroy-10);
    g2.drawString("x 0°", this.getSize().width-50 ,(float) this.centroy-10);
    g2.drawString("y 270°", (float) this.centrox+5 ,30);
    g2.drawString("y' 90°", (float) this.centrox+5 ,this.getSize().height-30);   
    // se dibuja una figura con forma de "flecha"
    g2.setStroke(new BasicStroke(2.0f));
    g2.draw(new QuadCurve2D.Double(this.centrox + 0, this.centroy + 50, this.centrox + 45,this.centroy + 45, this.centrox + 50, this.centroy + 0));                           
    g2.draw(new Line2D.Double(this.centrox + 0,this.centroy + 50,this.centrox + 10,this.centroy + 40));      
    g2.draw(new Line2D.Double(this.centrox + 0, this.centroy + 50,this.centrox + 14, this.centroy + 55));      
    
    //dibujamos unaas lineas que simularan el eje de coordenas X & Y
    g2.setStroke(new BasicStroke(1.0f));   
    g2.setColor(new Color(0,0,0));
    g2.draw(new Line2D.Double(this.centrox,0,this.centrox,this.centroy*2));      
    g2.draw(new Line2D.Double(0,this.centroy,this.centrox*2,this.centroy));      
    
    this.repaint();
  }
  
  //aplica la rotacion en grados
  public void setRotate(double r){
    this.rotate=r;
  }   
  //generamos un numero al azar de 0 a 360
  public void setRotateRandom(){
    this.rotate=(int)(Math.random()*360);
  }  
}


Lo que hacemos con esta clase es sobreescribir el metodo paintComponent() y luego utilizamos el objeto AffineTransform de Java2D para aplicar las transformacion, en este caso la ROTACION.
Para especificar el angulo de rotacion en Java2D se utilizan los radianes, asi que para ingresar un angulo, previamente debemos convertir esta utilizando Math.toRadians(). Al especificar la rotacion, tambien trasladamos el eje de coordendas al centro del JPanel (linea 49), si no hacemos esto, el punto de rotacion sera la esquina superior izquierda. Prueba cambiando estos valores y ve que pasa.
Cuando añadimos estas transformaciones al objeto Graphics2D (linea 53), todo los objetos que dibujemos despues se veran afectados, es por eso que antes guardamos el estado del objeto Graphics2D en otra variable oldt (linea 47) para que en cualquier momento volvamos a restaurar el estado original, como hacemos en la linea de codigo 70, para volver a dibujar el resto de los objetos.

3. Para implementar esta clase en la interfaz, hacemos lo siguiente:

Creamos una instancia a nuestro objeto j2dPanel,  inicializamos y añadimos al JFrame

01 public class Interfaz extends javax.swing.JFrame {
02     j2dPanel j2d;
03     /** Creates new form Interfaz */
04     public Interfaz() {
05         initComponents();
06         this.setTitle("AffineTransform: Rotación - by Mouse");
07         j2d = new j2dPanel(PANEL.getSize());
08         PANEL.add(j2d);
09         PANEL.repaint();
10     }
Para añadir los metodos a los jButton:


01     private void cmdRotar1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRotar1ActionPerformed
02          j2d.setRotate(Double.valueOf(txtRotate.getText()));           
03 }//GEN-LAST:event_cmdRotar1ActionPerformed
04 
05     private void cmdRotar2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdRotar2ActionPerformed
06         j2d.setRotateRandom();
07 }//GEN-LAST:event_cmdRotar2ActionPerformed


Y listo, solo falta ejecutar el proyecto

Notece que los objetos que estan afectados con el AffineTransform giran completamente, figuras, texto, incluso el degradado.

El codigo fuente hecho en netbeans 6.0
Click para descargar
La mejor forma de aprender es haciendo

5 comentarios:

Anónimo dijo...

Esta muy bueno tu blog, me ayudo mucho, el que necesitaba era el de rotacion en 2d, pero quisiera saber si no tienes tambien el de escalamiento y traslacion!!

Graciass!!

Unknown dijo...

Exelente amigo... muchas gracias me sirvio de mucho ... gracias

erik dijo...

eii que tal, tengo un problema con el programa a la hora de ponerle los grados a la rotacion, le doy clic en el boton rotar figura y me dice que hay error, y en el codigo me marca esta parte

this.centrox= this.size().width/2;
this.centroy = this.size().height/2;

donde doce .size tachado, sabes que pueda ser?

Unknown dijo...

y me dice que j2dPanel no tiene un metodo main, ¿se lo tengo que agregar?

mouse dijo...

¿como estas ejecutando el proyecto?

j2DPanel es un JPanel y no tiene metodo main. EL j2Dpanel lo debes implementar en el JFrame interfaz

Post recomendado