/* * Richard A. DeVenezia * June 7, 2004 * www.devenezia.com/java/affine * * An atypical example demonstrating how to implement * viewports and windows using AffineTransform. */ import java.awt.*; import java.awt.image.*; import java.awt.geom.*; import javax.swing.*; import java.text.DecimalFormat ; public class Sample { int w = 400; int h = 400; int dvx=0, dvy=0, dvw=w, dvh=h; double vllx=0, vlly=0, vurx=1, vury=1, vw=1, vh=1; double wllx=0, wlly=0, wurx=w, wury=h, ww=w, wh=h; BufferedImage buffer = new BufferedImage ( w,h, BufferedImage.TYPE_INT_RGB ); Graphics2D g = buffer.createGraphics(); AffineTransform initialTx = g.getTransform(); void setViewport (double x1, double y1, double x2, double y2) { // Viewport, fraction of buffer vllx = x1; vlly = y1; vurx = x2; vury = y2; vw = vurx - vllx; vh = vury - vlly; dvx = (int) Math.round( vllx * w); dvy = (int) Math.round((1-vury) * h); dvw = (int) Math.round( vw * w); dvh = (int) Math.round( vh * h); g.setTransform (initialTx); g.setClip (dvx,dvy,dvw,dvh); System.out.println ("vw:"+df.format(vw)+",vh:"+df.format(vh)); System.out.println ("dvx:"+dvx+",dvy:"+dvy+",dvw:"+dvw+",dvh:"+dvh); } void setWindow (double x1, double y1, double x2, double y2) { // Window, world coordinates wllx = x1; wlly = y1; wurx = x2; wury = y2; ww = wurx - wllx; wh = wury - wlly; System.out.println ("ww:"+ww+",wh:"+wh); } void setVWTransform () { // px = 0 + w * ( vllx + (WX - wllx) / (wurx - wllx) * (vurx - vllx) ) // py = h - h * ( vlly + (Wy - wlly) / (wury - wlly) * (vury - vlly) ) double kw = vw / ww; double kh = vh / wh; g.setTransform ( new AffineTransform ( kw*w, 0 , 0, -kh*h , (vllx-kw*wllx)*w, (1-vlly+kh*wlly)*h ) ); } void resetVWTransform () { setViewport (0,0,1,1); setWindow (0,0,w,h); vllx=0; vlly=0; vurx=1; vury=1; vw=1; vh=1; double wllx=0, wlly=0, wurx=100, wury=100, ww=100, wh=100; } void drawStuff () { g.setColor (Color.BLUE); for (int radius = 10; radius < 150; radius += 10) { g.drawOval (60-radius,60-radius,2*radius,2*radius); } } void show() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new JScrollPane(new JPanel() { protected void paintComponent(Graphics g) { g.fillRect(0, 0, getWidth(), getHeight()); g.drawImage(buffer, 0, 0, null); } public Dimension getPreferredSize() { return new Dimension(buffer.getWidth(), buffer.getHeight()); } })); frame.pack(); frame.show(); } DecimalFormat df = new DecimalFormat ("####.##"); public static void main(String args[]) { Sample s = new Sample(); s.g.setRenderingHint ( RenderingHints.KEY_TEXT_ANTIALIASING , RenderingHints.VALUE_TEXT_ANTIALIAS_ON); s.g.setRenderingHint ( RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON); s.g.setBackground (Color.WHITE); s.g.clearRect (0,0,s.w,s.h); // draw some circles and lines, untransformed s.drawStuff (); s.g.drawLine (40,40,100,100); s.g.drawRect (40,40,60,60); // specify viewport and window s.setViewport (.55,.55,.95,.95); s.setWindow (35,35,110,110); s.g.setColor (new Color (0x200000ff, true)); s.g.fillRect (0,0,s.w,s.h); s.setVWTransform (); s.drawStuff (); s.g.drawLine (40,40,100,100); s.g.drawRect (40,40,60,60); // specify viewport and window s.setViewport (.55,.05,.95,.45); s.setWindow (-10,-10,65,65); s.g.setColor (new Color (0x20ffff00, true)); s.g.fillRect (0,0,s.w,s.h); s.setVWTransform (); s.drawStuff (); s.g.drawLine (40,40,100,100); s.g.drawRect (40,40,60,60); // specify viewport and window // viewport aspect differs from window aspect, causing squarsh or squish s.setViewport (0,0,.24,.24); s.setWindow (-10,35,105,105); s.g.setColor (new Color (0x2000ff00, true)); s.g.fillRect (0,0,s.w,s.h); s.setVWTransform (); s.g.scale (1,1); s.drawStuff (); s.g.drawLine (40,40,100,100); s.g.drawRect (40,40,60,60); // specify viewport and window s.setViewport (.25,.25,.49,.49); s.setWindow (-150,-150,250,250); s.g.setColor (new Color (0x2000ff00, true)); s.g.fillRect (0,0,s.w,s.h); s.setVWTransform (); s.drawStuff (); s.g.drawLine (40,40,100,100); s.g.drawRect (40,40,60,60); try { javax.imageio.ImageIO.write (s.buffer, "png", new java.io.File ("sample.png")); } catch (Exception e) { System.out.println (e); } s.show(); } }