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.
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 }
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.
5 comentarios:
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!!
Exelente amigo... muchas gracias me sirvio de mucho ... gracias
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?
y me dice que j2dPanel no tiene un metodo main, ¿se lo tengo que agregar?
¿como estas ejecutando el proyecto?
j2DPanel es un JPanel y no tiene metodo main. EL j2Dpanel lo debes implementar en el JFrame interfaz
Publicar un comentario