El siguiente programa utiliza una Transformacion Lineal para pasar de las coordenadas (x,y) clasicas a las coordenadas (xj,yj) que son las que se utilizan para graficar con el lenguaje java (metodos "transformar_X_a_J(...)","transformar_J_a_X(...)").
s:escala
w:ancho del area de dibujo
h:alto del area de dibujo
El programa dibuja una linea recta (con el metodo "pintar_recta(...)") cuyos paramtros a, b, c, deacuerdo a la formula ax+by=c. pueden ser modificados.
Ademas el programa puede guardar el grafico como un archivo "*.jpg" con el metodo "guardarComoJPG()" donde lo mas relevante que hace este metodo es, crear un objeto "BufferedImage bi" y llamar al metodo "paint(bi.getGraphics())"(el metodo "paint" es donde se dibuja la escena) del panel de dibujo para tener la imagen en el objeto "bi", luego con los parametros de codificacion de imagen de las Clases "JPEGEncodeParam", y "JPEGImageEncoder" obtener el mapa de Bytes para guardar.
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JComboBox;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Color;
import java.awt.Font;
import java.awt.AlphaComposite;
public class Principal_Coordenadas implements ActionListener{
JTextArea jta_a=new JTextArea("5");
JTextArea jta_b=new JTextArea("7");
JTextArea jta_c=new JTextArea("0");
JComboBox jcb_escala;
Image image_fondo;
int ancho=360;
int alto=512;
JFrame ventana;
PanelCoordenadas panelCoordenadas;
public Principal_Coordenadas()
{
Font fuente=new Font("Adler", Font.PLAIN, 20);
String base=System.getProperty("user.dir");
System.out.println(base);
image_fondo = Toolkit.getDefaultToolkit().getImage(base+"/IMGA0631.jpg");
JButton calcular = new JButton("calcular");
calcular.setFont(fuente);
calcular.setBackground(Color.black);
calcular.setForeground(Color.white);
calcular.setToolTipText("para actualizar el grafico de la recta");
calcular.addActionListener(this);
JMenuBar jm_barraDeMenu=new JMenuBar();
JMenu jm_archivo = new JMenu("Archivo");
jm_archivo.setMnemonic(java.awt.event.KeyEvent.VK_A);
jm_archivo.setToolTipText("para guardar el grafico");
jm_archivo.setFont(fuente);
JMenuItem jmi_guardar_como_jpg = new JMenuItem("Guardar como JPG",java.awt.event.KeyEvent.VK_G);
jmi_guardar_como_jpg.setAccelerator (javax.swing.KeyStroke.getKeyStroke (java.awt.event.KeyEvent.VK_G,java.awt.event.ActionEvent.ALT_MASK));
jmi_guardar_como_jpg.setToolTipText("para guardar el grafico como .jpg");
jmi_guardar_como_jpg.addMouseListener(new java.awt.event.MouseListener()
{
public void mouseClicked(java.awt.event.MouseEvent ae)
{}
public void mouseExited(java.awt.event.MouseEvent ae)
{}
public void mouseEntered(java.awt.event.MouseEvent ae)
{}
public void mouseReleased(java.awt.event.MouseEvent ae)
{}
public void mousePressed(java.awt.event.MouseEvent ae)
{
guardarComoJPG();
}
});
jmi_guardar_como_jpg.setFont(fuente);
jm_archivo.add(jmi_guardar_como_jpg);
JMenuItem jmi_salir = new JMenuItem("Salir",java.awt.event.KeyEvent.VK_S);
jmi_salir.setAccelerator (javax.swing.KeyStroke.getKeyStroke (java.awt.event.KeyEvent.VK_S,java.awt.event.ActionEvent.ALT_MASK));
jmi_salir.setToolTipText("para salir de la aplicacion");
jmi_salir.setFont(fuente);
jmi_salir.addActionListener(this);
jm_archivo.add(jmi_salir);
jm_barraDeMenu.add(jm_archivo);
ventana = new JFrame();
ventana.setLayout( new BorderLayout() );
int x=(int)((Toolkit.getDefaultToolkit().getScreenSize().width-ancho)/2);
int y=(int)((Toolkit.getDefaultToolkit().getScreenSize().height-alto)/2);
ventana.setBounds(x, y, ancho,alto);
JPanel panel_recta=new JPanel();
jta_a.setColumns(1);
panel_recta.add(jta_a);
panel_recta.add(new JLabel("x +"));
jta_b.setColumns(1);
panel_recta.add(jta_b);
panel_recta.add(new JLabel("y ="));
jta_c.setColumns(1);
panel_recta.add(jta_c);
panel_recta.add(calcular);
panel_recta.add(new JLabel("Escala ="));
String[] opciones=new String[291];
for(int i=10;i<=opciones.length+9;i++)
{opciones[i-10]=""+i;}
jcb_escala=new javax.swing.JComboBox(opciones);
jcb_escala.setSelectedIndex(40);
jcb_escala.addActionListener(this);
panel_recta.add(jcb_escala);
ventana.setJMenuBar(jm_barraDeMenu);
ventana.add( panel_recta ,BorderLayout.NORTH);
ventana.add( panelCoordenadas = new PanelCoordenadas( Integer.parseInt((String)jcb_escala.getSelectedItem() )) ,BorderLayout.CENTER);
ventana.setVisible(true);
}
public class PanelCoordenadas extends JPanel
{
int escala=1;
/*boolean primeraVez=true;*/
java.awt.Rectangle area;
java.awt.image.BufferedImage bi;
Graphics g;
public PanelCoordenadas(int esc)
{
super();
escala=esc;
}
public void paint( Graphics g1 )
{
/*
if(primeraVez)
{
*/
java.awt.Dimension dim = getSize();
int w = dim.width;
int h = dim.height;
area = new java.awt.Rectangle(dim);
bi = (java.awt.image.BufferedImage)createImage(w, h);
g = bi.createGraphics();
/*primeraVez = false;*/
/*}*/
/* g.clearRect(0,0,area.width,area.height); */
/*Graphics2D g2=(Graphics2D)g1;*/
g1.clearRect(0,0,area.width,area.height);
Graphics2D g2=(Graphics2D)g;
g2.setBackground(Color.white);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP , 0.4f ));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(image_fondo, 0, 0,this.getWidth(), this.getHeight(), this);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP , 1.0f ));
pintar_ejes(g2);
pintar_recta(g2);
g1.drawImage(bi, 0, 0, this);
}
public void pintar_recta(Graphics2D g2d)
{
int a=Integer.parseInt(jta_a.getText());
int b=Integer.parseInt(jta_b.getText());
int c=Integer.parseInt(jta_c.getText());
java.awt.geom.Point2D[] p_= new java.awt.geom.Point2D[2];
double x0=- getSize().width/escala;
double y0=(c-a*x0)/b;
p_[0]= new java.awt.geom.Point2D.Double( x0 , y0 );
p_[0]= transformar_X_a_J((float)escala, p_[0]);
p_[0]= transformar_J_a_X((float)escala, p_[0]);
/* System.out.println("p_[0]"+p_[0]); */
double x1=getSize().width/escala;
double y1=(c-a*x1)/b;
p_[1]= new java.awt.geom.Point2D.Double( x1 , y1 );
p_[1]= transformar_X_a_J((float)escala, p_[1]);
p_[1]= transformar_J_a_X((float)escala, p_[1]);
/* System.out.println("p_[1]"+p_[1]); */
p_[0]= transformar_X_a_J((float)escala, p_[0]);
/*System.out.println("p_[0]"+p_[0]);*/
p_[1]= transformar_X_a_J((float)escala, p_[1]);
/* System.out.println("p_[1]"+ p_[1]); */
g2d.setColor(Color.red);
int ancho_linea=2;
java.awt.Stroke stroke = new java.awt.BasicStroke(ancho_linea, java.awt.BasicStroke.CAP_SQUARE,
java.awt.BasicStroke.JOIN_MITER, 1,
new float[] { 1, 0 }, 1);
g2d.setStroke(stroke);
g2d.draw(new java.awt.geom.Line2D.Double(p_[0].getX() ,p_[0].getY(), p_[1].getX(), p_[1].getY()));
}
public void pintar_ejes(java.awt.Graphics2D g2d)
{
int ancho_=getSize().width;
int alto_=getSize().height;
int n_f=(int)((ancho_/2)/escala);
g2d.setColor(java.awt.Color.DARK_GRAY);
g2d.setFont(new java.awt.Font("Helvetica",java.awt.Font.PLAIN,10));
for(int i=1;i<=n_f;i++)
{
g2d.drawLine( (int)(ancho_/2-i*escala),(int)(0),(int)(ancho_/2-i*escala),(int)(alto_) );
g2d.drawString("-"+i, (int)(ancho_/2-i*escala), (int)(alto_/2+12));
}
for(int i=1;i<=n_f;i++)
{
g2d.drawLine( (int)(ancho_/2+i*escala),(int)(0),(int)(ancho_/2+i*escala),(int)(alto_) );
g2d.drawString(""+i, (int)(ancho_/2+i*escala), (int)(alto_/2+12));
}
int n_c=(int)((alto_/2)/escala);
for(int i=1;i<=n_c;i++)
{
g2d.drawLine( (int)(0),(int)(alto_/2-i*escala),(int)(ancho_),(int)(alto_/2-i*escala) );
g2d.drawString(""+i, (int)(ancho_/2-12), (int)(alto_/2-i*escala));
}
for(int i=1;i<=n_c;i++)
{
g2d.drawLine( (int)(0),(int)(alto_/2+i*escala),(int)(ancho_),(int)(alto_/2+i*escala) );
g2d.drawString("-"+i, (int)(ancho_/2-12), (int)(alto_/2+i*escala));
}
{
java.awt.Stroke stroke_actual=g2d.getStroke();
java.awt.Stroke stroke = new java.awt.BasicStroke(1, java.awt.BasicStroke.CAP_SQUARE,
java.awt.BasicStroke.JOIN_MITER, 2,
new float[] { 2, 5 }, 5);
g2d.setStroke(stroke);
for(int i=0;i<=2*n_f;i++)
{
g2d.drawLine( (int)(ancho_/2-i*escala/2),(int)(0),(int)(ancho_/2-i*escala/2),(int)(alto_) );
}
for(int i=0;i<=2*n_f;i++)
{
g2d.drawLine( (int)(ancho_/2+i*escala/2),(int)(0),(int)(ancho_/2+i*escala/2),(int)(alto_) );
}
for(int i=0;i<=2*n_c;i++)
{
g2d.drawLine( (int)(0),(int)(alto_/2-i*escala/2),(int)(ancho_),(int)(alto_/2-i*escala/2) );
}
for(int i=0;i<=2*n_c;i++)
{
g2d.drawLine( (int)(0),(int)(alto_/2+i*escala/2),(int)(ancho_),(int)(alto_/2+i*escala/2) );
}
for(int i=0;i<=2*n_c+4;i++)
{
if(i%2==1)
g2d.draw(new java.awt.geom.Ellipse2D.Double(ancho_/2-i*escala/2,alto_/2-i*escala/2,i*escala,i*escala) );
}
g2d.setStroke(stroke_actual);
for(int i=0;i<=n_c+2;i++)
{
g2d.draw(new java.awt.geom.Ellipse2D.Double(ancho_/2-i*escala,alto_/2-i*escala,2*i*escala,2*i*escala) );
}
}
java.awt.Stroke stroke = new java.awt.BasicStroke(3, java.awt.BasicStroke.CAP_SQUARE,
java.awt.BasicStroke.JOIN_MITER, 2,
new float[] { 10, 5 }, 5);
g2d.setStroke(stroke);
g2d.setColor(java.awt.Color.BLACK);
/* eje y */
g2d.drawLine( (int)(ancho_/2),(int)(2),(int)(ancho_/2),(int)(alto_-2) );
/* eje x */
g2d.drawLine( (int)(2),(int)(alto_/2),(int)(ancho_-2),(int)(alto_/2) );
}
public java.awt.geom.Point2D transformar_J_a_X( float scale , java.awt.geom.Point2D pun )
{
java.awt.geom.Point2D p_salida;
int ancho_=getSize().width;
int alto_=getSize().height;
double x=( pun.getX()-(ancho_/2) )/scale;
double y=( -pun.getY()+(alto_/2) )/scale;
p_salida= new java.awt.geom.Point2D.Double( x , y );
return p_salida;
}
public java.awt.geom.Point2D transformar_X_a_J( float scale , java.awt.geom.Point2D pun )
{
java.awt.geom.Point2D p_salida;
int ancho_=getSize().width;
int alto_=getSize().height;
double x=( pun.getX()*scale+(ancho_/2) );
double y=( -pun.getY()*scale+(alto_/2) );
p_salida= new java.awt.geom.Point2D.Double( x , y );
return p_salida;
}
}
public void actionPerformed(ActionEvent ae)
{
if(ae.getActionCommand().equalsIgnoreCase("Salir"))
{
System.exit(0);
}
panelCoordenadas.escala = Integer.parseInt((String)jcb_escala.getSelectedItem());
ventana.repaint();
/*
if( ae.getSource() instanceof javax.swing.JComboBox )
{
String s = ae.getActionCommand();
if(s == "comboBoxChanged")
{
ventana.repaint();
}
}
*/
}
public void guardarComoJPG()
{
/* IMPORTANTE LEER!!!!!!!!!!!!!!!!!!!!!!!!!!!
* "¡Por favor no olvide colocar la extension del archivo *.jpg al guardar
* si no la maquina comenzara a hacer bip-bip-bip-bip-bip- y se colgara!");
* */
javax.swing.JFileChooser fileChooser = new javax.swing.JFileChooser();
String aux=System.getProperty("user.dir");
fileChooser.setCurrentDirectory( new java.io.File( aux ) );
fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter()
{ public String getDescription()
{
return ".jpg";
}
public boolean accept( java.io.File archivo )
{
boolean res = false;
String nombre = archivo.getName();
if( nombre.endsWith(".jpg") ||archivo.isDirectory()|| archivo.isFile())
res = true;
return res;
}
}
);
fileChooser.setFileSelectionMode(javax.swing.JFileChooser.FILES_ONLY);
int result= fileChooser.showSaveDialog(ventana);
if (result== javax.swing.JFileChooser.CANCEL_OPTION) return;
java.io.File name= fileChooser.getSelectedFile();
if(name.exists())
{
int i=javax.swing.JOptionPane.showConfirmDialog(null,"Esta seguro que quiere Sobrescribir el Archivo:\t \n"+name);
if(i==1 || i==2) return;
}
try {
/********************************************************************************/
int width=panelCoordenadas.getWidth();
int height=panelCoordenadas.getHeight();
java.awt.image.BufferedImage bi=new java.awt.image.BufferedImage(width, height, java.awt.image.BufferedImage.TYPE_3BYTE_BGR);
panelCoordenadas.paint(bi.getGraphics());
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
com.sun.image.codec.jpeg.JPEGEncodeParam param = com.sun.image.codec.jpeg.JPEGCodec.getDefaultJPEGEncodeParam(bi);
param.setQuality(0.90f, true);
com.sun.image.codec.jpeg.JPEGImageEncoder enc = com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(out, param);
enc.encode(bi);
/*bi.flush();*/
byte[] imageBytes = out.toByteArray();
java.io.FileOutputStream binFile;
if(name.getAbsolutePath().endsWith(".jpg"))
binFile = new java.io.FileOutputStream(name.getAbsolutePath());
else
binFile = new java.io.FileOutputStream(name+".jpg");
binFile.write(imageBytes);
binFile.close();
/********************************************************************************/
}
catch (java.io.IOException ioException) {
javax.swing.JOptionPane.showMessageDialog(null,"Error en el archivo","Error",javax.swing.JOptionPane.ERROR_MESSAGE);
}
}
public static void main(String[] ar)
{
new Principal_Coordenadas();
}
}
IMPORTANTE unir los cuatro pedazos para copilar y ejecutar.
Palabras clave: Java 2d, jpg, Transformacion Lineal