La clase QuadCurve2D de Java2D nos permite dibujar una curva basado en ecuaciones matematicas, esta curva tambien se la conoce con el nombre de Curva Cuadratica de Bezier.
Esta curva funciona de la siguiente manera: Se establecen dos puntos (P1 y P2) que establecen los extremos de un segmento curvo, y tambien se define un tercer punto (Punto de Control) el cual nos permite DEFORMAR la curva
La ecuacion con la cual se generan los diferentes puntos que forman la curva es:
El valor de (t) va de 0 hasta 1, donde para un valor de 0 corresponde a las coordenadas de P1 y para un valor de 1, equivale a P2
Proyecto:
Porque se aprende mejor haciendo, dejo la teoria de las matematicas para su propia investigacion, lo que ahora haremos en este tutorial, sera construir una aplicacion en netbeans donde dibujaremos la curva QuadCurve2D, de dos maneras, una de ellas utilizando la clase propia de Java2D y la segunda donde haremos uso de la formula escrita mas arriba, asi podremos apreciar como java2d construye esta figura. Manos a la obra.
1. Crea un nuevo proyecto en Netbeans, Añade un nuevo JFrame: Interfaz y una clase nueva , llamala "miPaint.java", al JFrame interfaz, añadele los siguiente objetos, no te olvides de cambiarle los nombres como en la imagen:
2. A la clase miPaint.java añade el codigo:
01 import java.awt.BasicStroke; 02 import java.awt.Color; 03 import java.awt.Dimension; 04 import java.awt.Font; 05 import java.awt.Graphics; 06 import java.awt.Graphics2D; 07 import java.awt.geom.Line2D; 08 import java.awt.geom.Point2D; 09 import java.awt.geom.QuadCurve2D; 10 import java.text.NumberFormat; 11 import javax.swing.JOptionPane; 12 import javax.swing.JPanel; 13 /** 14 * @web http://jc-mouse.blogspot.com/ 15 * @author Mouse 16 */ 17 public class miPaint extends JPanel { 18 private Point2D Punto1; 19 private Point2D Punto2; 20 private Point2D Punto3; 21 private Point2D Punto; 22 private boolean band=true; 23 float rango=0.01f; 24 25 public miPaint(Dimension d){ 26 this.setPreferredSize(d); 27 this.setSize(d); 28 this.setVisible(true); 29 this.repaint(); 30 //se crean las coordenas al azar 31 this.Punto1 = new Point2D.Double(getCoordenada(),getCoordenada()); 32 this.Punto2 = new Point2D.Double(getCoordenada(),getCoordenada()); 33 this.Punto3 = new Point2D.Double(getCoordenada(),getCoordenada()); 34 } 35 //actualiza nuevas coordenadas a los Puntos 36 public void setPoint2D(String x1,String y1,String x2,String y2,String x3,String y3, boolean b){ 37 this.Punto1 = new Point2D.Float(Float.valueOf(x1),Float.valueOf(y1)); 38 this.Punto2 = new Point2D.Float(Float.valueOf(x3),Float.valueOf(y3)); 39 this.Punto3 = new Point2D.Float(Float.valueOf(x2),Float.valueOf(y2)); 40 this.band=b; 41 } 42 43 @Override 44 public void paintComponent(Graphics g){ 45 super.paintComponent(g); 46 Graphics2D g2 = (Graphics2D)g; 47 //grosor de pincel 48 g2.setStroke(new BasicStroke(2.0f)); 49 //color de pincel 50 g2.setColor(new Color(0,0,200)); 51 if(band){ 52 Dibujar_QuadCurve2D(g2); 53 }else{ 54 Dibujar_Bezier(g2); 55 } 56 this.repaint(); 57 Mostrar_Datos(g2); 58 } 59 60 //dibuja la curva con la funcion de java2d QuadCurve2D 61 public void Dibujar_QuadCurve2D(Graphics2D g2){ 62 g2.draw(new QuadCurve2D.Double(Punto1.getX(), Punto1.getY(), Punto2.getX(), Punto2.getY(), 63 Punto3.getX(), Punto3.getY())); 64 } 65 66 //dibuja la curva con la funcion de la curva cuadratica de Bezier 67 //(1-t)^2*p1 + 2t(1-t)p2 + t^2*p3 68 public void Dibujar_Bezier(Graphics2D g2){ 69 float f1; 70 float f2; 71 float t=0; 72 while (t<=1.0){ 73 //obtiene las coordenadas 74 f1 = (float) (((1-t)*(1-t) * Punto1.getX()) + 2 * t * (1 - t) * Punto2.getX() + (t * t) 75 * Punto3.getX()); 76 f2 = (float) (((1-t)*(1-t) * Punto1.getY()) + 2 * t * (1 - t) * Punto2.getY() + (t * t) 77 * Punto3.getY()); 78 //crea un punto con esas coordenadas 79 Punto = new Point2D.Float(f1,f2); 80 //dibuja el punto 81 g2.draw(new Line2D.Double(Punto.getX(),Punto.getY(),Punto.getX(),Punto.getY())); 82 t = (float) (t + rango); 83 } 84 85 } 86 87 // 88 public void setRango(String x){ 89 if((Float.valueOf(x)<=1)&&(Float.valueOf(x)>0.001)){ 90 this.rango=Float.valueOf(x); 91 }else{ 92 JOptionPane.showMessageDialog(this,"Solo valores entre [0.001 y 1.0]"); 93 } 94 95 } 96 /* metodos auxiliares */ 97 98 //muestra lascoordenas de los puntos P1,P2 Y P3 99 //dibuja las lineas que estos forman 100 private void Mostrar_Datos(Graphics2D g2){ 101 g2.setStroke(new BasicStroke(1.0f)); 102 g2.setColor(new Color(0,0,0)); 103 g2.draw(new Line2D.Double(Punto1.getX(), Punto1.getY(), Punto2.getX(), Punto2.getY())); 104 g2.draw(new Line2D.Double(Punto3.getX(), Punto3.getY(), Punto2.getX(), Punto2.getY())); 105 dibuja_coordenada(g2,Punto1.getX(), Punto1.getY(),"Punto 1"); 106 dibuja_coordenada(g2,Punto2.getX(), Punto2.getY(),"Punto de Control"); 107 dibuja_coordenada(g2,Punto3.getX(), Punto3.getY(),"Punto 2"); 108 } 109 110 //dibuja las coordenas dadas un punto P1,P2 111 private void dibuja_coordenada(Graphics2D g2,double x, double y,String t){ 112 NumberFormat mf = NumberFormat.getInstance(); 113 mf.setMaximumFractionDigits(2); 114 g2.setColor(new Color(255,0,0)); 115 g2.setFont(new Font("Arial", Font.BOLD, 11)); 116 g2.drawString(t + " ("+mf.format(x)+","+mf.format(y)+")",(float) (x+4),(float) (y-10)); 117 g2.setStroke(new BasicStroke(4.5f)); 118 g2.draw(new Line2D.Double(x,y,x,y)); 119 } 120 121 //genera un valor al azar 122 private double getCoordenada(){ 123 return ((Math.random()*350)+50); 124 } 125 126 127 }
Esta clase implementamos un nuevo JPanel al cual se le modificar su metodo paintComponent para que pueda dibujar las figuras con Java2D, asi tambien, solo para motivos ilustrativos, tambien se dibujaran las lineas entre P1-P3 y P2-P3 para que se pueda ver las lineas que estas forman al trazar la curva bezier.
3. Para implementar esta clase en la interfaz, debemos hacer los siiguientes cambios:
OJO: No copies y pegues, chekea donde va cada linea de codigo.
Con esto nuestra pequeña aplicacion estara lista para funcionar
Aqui dejo el codigo fuente en netbeans 6.0
3. Para implementar esta clase en la interfaz, debemos hacer los siiguientes cambios:
01 public class interfaz extends javax.swing.JFrame { 02 miPaint paint; 03 /** Creates new form interfaz */ 04 public interfaz() { 05 initComponents(); 06 this.setTitle("JAVA2D - QuadCurve2D - [by Mouse]"); 07 this.setLocationRelativeTo(null); 08 paint = new miPaint(jPanel1.getSize()); 09 jPanel1.add(paint); 10 } 11 12 private void bt_1ActionPerformed(java.awt.event.ActionEvent evt) { 13 paint.setPoint2D(p1x.getText(), p1y.getText(), p2x.getText(), p2y.getText(), pcx.getText(), pcy.getText(),true); 14 } 15 16 private void bt_2ActionPerformed(java.awt.event.ActionEvent evt) { 17 paint.setPoint2D(p1x.getText(), p1y.getText(), p2x.getText(), p2y.getText(), pcx.getText(), pcy.getText(),false); 18 } 19 20 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 21 paint.setRango(f.getText()); 22 }
OJO: No copies y pegues, chekea donde va cada linea de codigo.
Con esto nuestra pequeña aplicacion estara lista para funcionar
Aqui dejo el codigo fuente en netbeans 6.0
Muy bueno !
ResponderEliminarEs excelente, se necesitan mas personas asi en este mundo que compartan sus conocimientos...
ResponderEliminarfelicitaciones
soy nuevo en esto de java y me gustaría descargar tu código para no errar al solo copiar y pegar pero el link ya no funciona me lo puedes pasar se que ya es de algunos años y espero que todavía lo tengas.
ResponderEliminarsaludos y excelente trabajo.
Muchas gracias. Excelente ejemplo.
ResponderEliminar