Java/2D Graphics GUI/Transform
Содержание
- 1 AffineTransform demo
- 2 Coordinate Demo
- 3 Create an complex shape by rotating an ellipse.
- 4 Creates and returns a translated shape.
- 5 Line transformation, rotation, shear,scale
- 6 Perform shearing: use share() method.
- 7 Resizes or translates a Shape
- 8 Rotates a shape about the specified coordinates.
- 9 Rotating a Drawn Image
- 10 Rotating a Shape with AffineTransform
- 11 Rotating image using Java 2D AffineTransform class
- 12 Rotation and coordinate translation
- 13 Scaling a Drawn Image
- 14 Scaling an object
- 15 Scaling a Shape with AffineTransform
- 16 Shearing a Drawn Image
- 17 Shearing a Shape with AffineTransform
- 18 Transform Demo
- 19 Transforme Rotation demo
- 20 Transform Rotation Translation
- 21 Transform Scale
- 22 Transform Shear
- 23 Transform Translated Rotation
- 24 Transform Translation
- 25 Transform Translation and Rotation
- 26 Translating a Drawn Image
- 27 Translating a Shape with AffineTransform
AffineTransform demo
<source lang="java"> import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class AffineTransformApp extends JFrame {
DisplayPanel displayPanel; JComboBox scaleXval, scaleYval, shearXval, shearYval; String[] scaleValues = { "0.10", "0.25", "0.50", "0.75", "1.00", "1.25", "1.50", "1.75", "2.00" }; String[] shearValues = { "0.00", "0.25", "0.50", "0.75", "1.00" }; public AffineTransformApp() { super(); Container container = getContentPane(); displayPanel = new DisplayPanel(); container.add(displayPanel); JPanel panel = new JPanel(); panel.setLayout(new GridLayout(2, 4, 5, 5)); scaleXval = new JComboBox(scaleValues); scaleXval.setSelectedItem("1.00"); scaleXval.addActionListener(new ComboBoxListener()); scaleYval = new JComboBox(scaleValues); scaleYval.setSelectedItem("1.00"); scaleYval.addActionListener(new ComboBoxListener()); shearXval = new JComboBox(shearValues); shearXval.setSelectedItem("0.00"); shearXval.addActionListener(new ComboBoxListener()); shearYval = new JComboBox(shearValues); shearYval.setSelectedItem("0.00"); shearYval.addActionListener(new ComboBoxListener()); panel.add(new JLabel("Scale X value:")); panel.add(scaleXval); panel.add(new JLabel("Scale Y value:")); panel.add(scaleYval); panel.add(new JLabel("Shear X value:")); panel.add(shearXval); panel.add(new JLabel("Shear Y value:")); panel.add(shearYval); container.add(BorderLayout.SOUTH, panel); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); setSize(displayPanel.getWidth(), displayPanel.getHeight() + 10); setVisible(true); } public static void main(String arg[]) { new AffineTransformApp(); } class ComboBoxListener implements ActionListener { public void actionPerformed(ActionEvent e) { JComboBox temp = (JComboBox) e.getSource(); if (temp == scaleXval) { displayPanel.scalex = Double.parseDouble((String) temp .getSelectedItem()); displayPanel.applyValue(true, false); displayPanel.applyFilter(); displayPanel.repaint(); } else if (temp == scaleYval) { displayPanel.scaley = Double.parseDouble((String) temp .getSelectedItem()); displayPanel.applyValue(true, false); displayPanel.applyFilter(); displayPanel.repaint(); } else if (temp == shearXval) { displayPanel.shearx = Double.parseDouble((String) temp .getSelectedItem()); displayPanel.applyValue(false, true); displayPanel.applyFilter(); displayPanel.repaint(); } else if (temp == shearYval) { displayPanel.sheary = Double.parseDouble((String) temp .getSelectedItem()); displayPanel.applyValue(false, true); displayPanel.applyFilter(); displayPanel.repaint(); } } }
} class DisplayPanel extends JLabel {
Image displayImage; BufferedImage biSrc, biDest; BufferedImage bi; Graphics2D big; AffineTransform transform; double scalex = 1.0; double scaley = 1.0; double shearx = 1.0; double sheary = 1.0; DisplayPanel() { setBackground(Color.black); loadImage(); setSize(displayImage.getWidth(this), displayImage.getWidth(this)); // panel createBufferedImages(); transform = new AffineTransform(); } public void loadImage() { displayImage = Toolkit.getDefaultToolkit().getImage( "largejexpLogo.jpg"); MediaTracker mt = new MediaTracker(this); mt.addImage(displayImage, 1); try { mt.waitForAll(); } catch (Exception e) { System.out.println("Exception while loading."); } if (displayImage.getWidth(this) == -1) { System.out.println(" Missing .jpg file"); System.exit(0); } } public void createBufferedImages() { biSrc = new BufferedImage(displayImage.getWidth(this), displayImage .getHeight(this), BufferedImage.TYPE_INT_RGB); big = biSrc.createGraphics(); big.drawImage(displayImage, 0, 0, this); bi = biSrc; biDest = new BufferedImage(displayImage.getWidth(this), displayImage .getHeight(this), BufferedImage.TYPE_INT_RGB); } public void applyValue(boolean scale, boolean shear) { if (scale) { transform.setToScale(scalex, scaley); scale = false; } else if (shear) { transform.setToShear(shearx, sheary); shear = false; } } public void applyFilter() { AffineTransformOp op = new AffineTransformOp(transform, null); Graphics2D biDestG2D = biDest.createGraphics(); biDestG2D .clearRect(0, 0, biDest.getWidth(this), biDest.getHeight(this)); op.filter(biSrc, biDest); bi = biDest; } public void reset() { big.setColor(Color.black); big.clearRect(0, 0, bi.getWidth(this), bi.getHeight(this)); big.drawImage(displayImage, 0, 0, this); } public void update(Graphics g) { g.clearRect(0, 0, getWidth(), getHeight()); paintComponent(g); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2D = (Graphics2D) g; g2D.drawImage(bi, 0, 0, this); }
}
</source>
Coordinate Demo
<source lang="java"> /*
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * -Redistribution of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */
/* CoordinatesDemo.java is a 1.4 application that requires no other files. */ import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.Point; import java.awt.event.MouseEvent; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.event.MouseInputListener; /*
* This displays a framed area. As the user moves the cursor over the area, a * label displays the cursor"s location. When the user clicks, the area displays * a 7x7 dot at the click location. */
public class CoordinatesDemo {
private JLabel label; private Point clickPoint, cursorPoint; private void buildUI(Container container) { container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS)); CoordinateArea coordinateArea = new CoordinateArea(this); container.add(coordinateArea); label = new JLabel(); resetLabel(); container.add(label); //Align the left edges of the components. coordinateArea.setAlignmentX(Component.LEFT_ALIGNMENT); label.setAlignmentX(Component.LEFT_ALIGNMENT); //redundant } public void updateCursorLocation(int x, int y) { if (x < 0 || y < 0) { cursorPoint = null; updateLabel(); return; } if (cursorPoint == null) { cursorPoint = new Point(); } cursorPoint.x = x; cursorPoint.y = y; updateLabel(); } public void updateClickPoint(Point p) { clickPoint = p; updateLabel(); } public void resetLabel() { cursorPoint = null; updateLabel(); } protected void updateLabel() { String text = ""; if ((clickPoint == null) && (cursorPoint == null)) { text = "Click or move the cursor within the framed area."; } else { if (clickPoint != null) { text += "The last click was at (" + clickPoint.x + ", " + clickPoint.y + "). "; } if (cursorPoint != null) { text += "The cursor is at (" + cursorPoint.x + ", " + cursorPoint.y + "). "; } } label.setText(text); } /** * Create the GUI and show it. For thread safety, this method should be * invoked from the event-dispatching thread. */ private static void createAndShowGUI() { //Make sure we have nice window decorations. JFrame.setDefaultLookAndFeelDecorated(true); //Create and set up the window. JFrame frame = new JFrame("CoordinatesDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Set up the content pane. CoordinatesDemo controller = new CoordinatesDemo(); controller.buildUI(frame.getContentPane()); //Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application"s GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } public static class CoordinateArea extends JComponent implements MouseInputListener { Point point = null; CoordinatesDemo controller; Dimension preferredSize = new Dimension(400, 75); Color gridColor; public CoordinateArea(CoordinatesDemo controller) { this.controller = controller; //Add a border of 5 pixels at the left and bottom, //and 1 pixel at the top and right. setBorder(BorderFactory.createMatteBorder(1, 5, 5, 1, Color.RED)); addMouseListener(this); addMouseMotionListener(this); setBackground(Color.WHITE); setOpaque(true); } public Dimension getPreferredSize() { return preferredSize; } protected void paintComponent(Graphics g) { //Paint background if we"re opaque. if (isOpaque()) { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); } //Paint 20x20 grid. g.setColor(Color.GRAY); drawGrid(g, 20); //If user has chosen a point, paint a small dot on top. if (point != null) { g.setColor(getForeground()); g.fillRect(point.x - 3, point.y - 3, 7, 7); } } //Draws a 20x20 grid using the current color. private void drawGrid(Graphics g, int gridSpace) { Insets insets = getInsets(); int firstX = insets.left; int firstY = insets.top; int lastX = getWidth() - insets.right; int lastY = getHeight() - insets.bottom; //Draw vertical lines. int x = firstX; while (x < lastX) { g.drawLine(x, firstY, x, lastY); x += gridSpace; } //Draw horizontal lines. int y = firstY; while (y < lastY) { g.drawLine(firstX, y, lastX, y); y += gridSpace; } } //Methods required by the MouseInputListener interface. public void mouseClicked(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (point == null) { point = new Point(x, y); } else { point.x = x; point.y = y; } controller.updateClickPoint(point); repaint(); } public void mouseMoved(MouseEvent e) { controller.updateCursorLocation(e.getX(), e.getY()); } public void mouseExited(MouseEvent e) { controller.resetLabel(); } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseDragged(MouseEvent e) { } }
}
</source>
Create an complex shape by rotating an ellipse.
<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import javax.swing.JFrame; import javax.swing.JPanel; public class RotateTransformed extends JPanel {
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130); for (double i = 0; i < 360; i += 5) { AffineTransform at = AffineTransform.getTranslateInstance(400 / 2, 400 / 2); at.rotate(Math.toRadians(i)); g2.draw(at.createTransformedShape(e)); } } public static void main(String[] args) { JFrame frame = new JFrame(); frame.add(new RotateTransformed()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400, 400); frame.setVisible(true); }
}
</source>
Creates and returns a translated shape.
<source lang="java"> /*
* JCommon : a free general purpose class library for the Java(tm) platform * * * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jcommon/index.html * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------------- * ShapeUtilities.java * ------------------- * (C)opyright 2003-2008, by Object Refinery Limited and Contributors. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): -; * * $Id: ShapeUtilities.java,v 1.18 2008/06/02 06:58:28 mungady Exp $ * * Changes * ------- * 13-Aug-2003 : Version 1 (DG); * 16-Mar-2004 : Moved rotateShape() from RefineryUtilities.java to here (DG); * 13-May-2004 : Added new shape creation methods (DG); * 30-Sep-2004 : Added createLineRegion() method (DG); * Moved drawRotatedShape() method from RefineryUtilities class * to this class (DG); * 04-Oct-2004 : Renamed ShapeUtils --> ShapeUtilities (DG); * 26-Oct-2004 : Added a method to test the equality of two Line2D * instances (DG); * 10-Nov-2004 : Added new translateShape() and equal(Ellipse2D, Ellipse2D) * methods (DG); * 11-Nov-2004 : Renamed translateShape() --> createTranslatedShape() (DG); * 07-Jan-2005 : Minor Javadoc fix (DG); * 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG); * 21-Jan-2005 : Modified return type of RectangleAnchor.coordinates() * method (DG); * 22-Feb-2005 : Added equality tests for Arc2D and GeneralPath (DG); * 16-Mar-2005 : Fixed bug where equal(Shape, Shape) fails for two Polygon * instances (DG); * 01-Jun-2008 : Fixed bug in equal(GeneralPath, GeneralPath) method (DG); * */
import java.awt.Shape; import java.awt.geom.AffineTransform; /**
* Utility methods for {@link Shape} objects. * * @author David Gilbert */
public class Main {
/**
* Creates and returns a translated shape.
*
* @param shape the shape (null
not permitted).
* @param transX the x translation (in Java2D space).
* @param transY the y translation (in Java2D space).
*
* @return The translated shape.
*/
public static Shape createTranslatedShape(final Shape shape,
final double transX,
final double transY) {
if (shape == null) {
throw new IllegalArgumentException("Null "shape" argument.");
}
final AffineTransform transform = AffineTransform.getTranslateInstance(
transX, transY);
return transform.createTransformedShape(shape);
}
}
</source>
Line transformation, rotation, shear,scale
<source lang="java"> import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.geom.Line2D; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class House extends JPanel {
MyCanvas canvas; JSlider sliderTransX, sliderTransY, sliderRotateTheta, sliderRotateX, sliderRotateY, sliderScaleX, sliderScaleY, sliderWidth; double transX = 0.0; double transY = 0.0; double rotateTheta = 0.0; double rotateX = 150.0; double rotateY = 150.0; double scaleX = 1.0; double scaleY = 1.0; float width = 1.0f; public House() { super(new BorderLayout()); JPanel controlPanel = new JPanel(new GridLayout(3, 3)); add(controlPanel, BorderLayout.NORTH); controlPanel.add(new JLabel("Translate(dx,dy): ")); sliderTransX = setSlider(controlPanel, JSlider.HORIZONTAL, 0, 300, 150, 100, 50); sliderTransY = setSlider(controlPanel, JSlider.HORIZONTAL, 0, 300, 150, 100, 50); // To control rotation controlPanel.add(new JLabel("Rotate(Theta,ox,oy): ")); sliderRotateTheta = setSlider(controlPanel, JSlider.HORIZONTAL, 0, 360, 0, 90, 45); JPanel subPanel = new JPanel(); subPanel.setLayout(new GridLayout(1, 2)); sliderRotateX = setSlider(subPanel, JSlider.HORIZONTAL, 0, 300, 150, 150, 50); sliderRotateY = setSlider(subPanel, JSlider.HORIZONTAL, 0, 300, 150, 150, 50); controlPanel.add(subPanel); // To control scaling controlPanel.add(new JLabel("Scale(sx,sy)x10E-2:")); sliderScaleX = setSlider(controlPanel, JSlider.HORIZONTAL, 0, 200, 100, 100, 10); sliderScaleY = setSlider(controlPanel, JSlider.HORIZONTAL, 0, 200, 100, 100, 10); // To control width of line segments JLabel label4 = new JLabel("Width Control:", JLabel.RIGHT); sliderWidth = new JSlider(JSlider.HORIZONTAL, 0, 20, 1); sliderWidth.setPaintTicks(true); sliderWidth.setMajorTickSpacing(5); sliderWidth.setMinorTickSpacing(1); sliderWidth.setPaintLabels(true); sliderWidth.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { width = sliderWidth.getValue(); canvas.repaint(); } }); JPanel widthPanel = new JPanel(); widthPanel.setLayout(new GridLayout(1, 2)); widthPanel.add(label4); widthPanel.add(sliderWidth); add(widthPanel, BorderLayout.SOUTH); canvas = new MyCanvas(); add(canvas, "Center"); } public JSlider setSlider(JPanel panel, int orientation, int minimumValue, int maximumValue, int initValue, int majorTickSpacing, int minorTickSpacing) { JSlider slider = new JSlider(orientation, minimumValue, maximumValue, initValue); slider.setPaintTicks(true); slider.setMajorTickSpacing(majorTickSpacing); slider.setMinorTickSpacing(minorTickSpacing); slider.setPaintLabels(true); slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { JSlider tempSlider = (JSlider) e.getSource(); if (tempSlider.equals(sliderTransX)) { transX = sliderTransX.getValue() - 150.0; canvas.repaint(); } else if (tempSlider.equals(sliderTransY)) { transY = sliderTransY.getValue() - 150.0; canvas.repaint(); } else if (tempSlider.equals(sliderRotateTheta)) { rotateTheta = sliderRotateTheta.getValue() * Math.PI / 180; canvas.repaint(); } else if (tempSlider.equals(sliderRotateX)) { rotateX = sliderRotateX.getValue(); canvas.repaint(); } else if (tempSlider.equals(sliderRotateY)) { rotateY = sliderRotateY.getValue(); canvas.repaint(); } else if (tempSlider.equals(sliderScaleX)) { if (sliderScaleX.getValue() != 0.0) { scaleX = sliderScaleX.getValue() / 100.0; canvas.repaint(); } } else if (tempSlider.equals(sliderScaleY)) { if (sliderScaleY.getValue() != 0.0) { scaleY = sliderScaleY.getValue() / 100.0; canvas.repaint(); } } } }); panel.add(slider); return slider; } class MyCanvas extends Canvas { public void paint(Graphics g) { Graphics2D g2D = (Graphics2D) g; g2D.translate(transX, transY); g2D.rotate(rotateTheta, rotateX, rotateY); g2D.scale(scaleX, scaleY); BasicStroke stroke = new BasicStroke(width); g2D.setStroke(stroke); drawHome(g2D); } public void drawHome(Graphics2D g2D) { Line2D line1 = new Line2D.Float(100f, 200f, 200f, 200f); Line2D line2 = new Line2D.Float(100f, 200f, 100f, 100f); Line2D line3 = new Line2D.Float(100f, 100f, 150f, 50f); Line2D line4 = new Line2D.Float(150f, 50f, 200f, 100f); Line2D line5 = new Line2D.Float(200f, 100f, 200f, 200f); Line2D line6 = new Line2D.Float(140f, 200f, 140f, 150f); Line2D line7 = new Line2D.Float(140f, 150f, 160f, 150f); Line2D line8 = new Line2D.Float(160f, 150f, 160f, 200f); g2D.draw(line1); g2D.draw(line2); g2D.draw(line3); g2D.draw(line4); g2D.draw(line5); g2D.draw(line6); g2D.draw(line7); g2D.draw(line8); } } public static void main(String[] a) { JFrame f = new JFrame(); f.getContentPane().add(new House()); f.setDefaultCloseOperation(1); f.setSize(700, 550); f.setVisible(true); }
}
</source>
<source lang="java"> import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import javax.swing.JFrame; import javax.swing.JPanel; public class Shear extends JPanel {
public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; AffineTransform tx1 = new AffineTransform(); tx1.translate(50, 90); g2d.setTransform(tx1); g2d.setColor(Color.green); g2d.drawRect(0, 0, 80, 50); AffineTransform tx2 = new AffineTransform(); tx2.translate(50, 90); tx2.shear(0, 1); g2d.setTransform(tx2); g2d.setColor(Color.blue); g2d.draw(new Rectangle(0, 0, 80, 50)); } public static void main(String[] args) { JFrame frame = new JFrame("Shearing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new Shear()); frame.setSize(330, 270); frame.setLocationRelativeTo(null); frame.setVisible(true); }
}
</source>
Resizes or translates a Shape
<source lang="java"> /**
* * JFreeReport : a free Java reporting library * * * Project Info: http://reporting.pentaho.org/ * * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------ * ShapeTransform.java * ------------ * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors. */
import java.awt.Dimension; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Dimension2D; import java.awt.geom.GeneralPath; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RectangularShape; /**
* Utility class, which resizes or translates a Shape. The class contains * special handlers for Rectangles and Lines. * * @author Thomas Morgner */
public final strictfp class ShapeTransform {
// some constants for the cohenen-algorithmus /** * Flag for point lying left of clipping area. */ public static final int LEFT = 0x01; /** * Flag for point lying between horizontal bounds of area. */ public static final int H_CENTER = 0x02; /** * Flag for point lying right of clipping area. */ public static final int RIGHT = 0x04; /** * Flag for point lying "below" clipping area. */ public static final int BELOW = 0x10; /** * Flag for point lying between vertical bounds of clipping area. */ public static final int V_CENTER = 0x20; /** * Flag for point lying "above" clipping area. */ public static final int ABOVE = 0x40; /** A simple way to handle rounding errors. */ private static final double DELTA = 0.000001; /** * Mask for points which are inside. */ public static final int INSIDE = H_CENTER | V_CENTER; /** * Mask for points which are outside. */ public static final int OUTSIDE = LEFT | RIGHT | BELOW | ABOVE; /** * Default constructor. */ private ShapeTransform() { } /** * Resizes a line. Instead of creating a GeneralPath (as AffineTransform"s * scale would do) we modify the line itself. * * @param line * the line that should be scaled * @param width * the new width of the line bounds * @param height * the new height of the line bounds * @return the scale Line2D object. */ private static Line2D resizeLine(final Line2D line, final double width, final double height) { final Line2D newLine = getNormalizedLine(line); final Point2D p1 = newLine.getP1(); final Point2D p2 = newLine.getP2(); final double normPointX = (p1.getX() - p2.getX()); final double normPointY = (p1.getY() - p2.getY()); final double scaleX = (normPointX == 0) ? 1 : width / Math.abs(normPointX); final double scaleY = (normPointY == 0) ? 1 : height / Math.abs(normPointY); p2.setLocation((p2.getX() - p1.getX()) * scaleX + p1.getX(), (p2.getY() - p1.getY()) * scaleY + p1.getY()); newLine.setLine(p1, p2); return newLine; } /** * Normalize the line; the point with the lowest X is the primary point, if * both points have the same X, that point with the lowest Y value wins. * * @param line * the original line * @return the normalized line */ private static Line2D getNormalizedLine(final Line2D line) { final Line2D lineClone = (Line2D) line.clone(); final Point2D p1 = line.getP1(); final Point2D p2 = line.getP2(); if (p1.getX() < p2.getX()) { return lineClone; } if (p1.getX() > p2.getX()) { lineClone.setLine(p2, p1); return lineClone; } if (p1.getY() < p2.getY()) { return lineClone; } lineClone.setLine(p2, p1); return lineClone; } /** * Resizes a shape, so that the shape has the given width and height, but the * origin of the shape does not change. <p/> Unlike the AffineTransform, this * method tries to preserve the Shape"s Type. * * @param s * the shape * @param width * the new width * @param height * the new height * @return the resized shape. */ public static Shape resizeShape(final Shape s, final float width, final float height) { if (s instanceof Line2D) { return resizeLine((Line2D) s, width, height); } if (s instanceof RectangularShape) { return resizeRect((RectangularShape) s, width, height); } return transformShape(s, true, false, new Dimension((int) width, (int) height)); } /** * Resizes a rectangle. This works for real rectangles and produces funny * results for RoundRects etc .. * * @param rectangularShape * the rectangle * @param width * the new width of the rectangle * @param height * the new height of the rectangle. * @return the resized rectangle. */ public static Shape resizeRect(final RectangularShape rectangularShape, final double width, final double height) { final RectangularShape retval = (RectangularShape) rectangularShape.clone(); retval.setFrame(retval.getX(), retval.getY(), width, height); return retval; } /** * Translates the given shape. The shape is translated to the origin supplied * inpoint
. If scaling is requested, the shape will also be * scaled using an AffineTransform. * * @param s * the shape that should be transformed * @param scale * true, if the shape should be scaled, false otherwise * @param keepAR * true, if the scaled shape should keep the aspect ratio * @param width * the target width. * @param height * the target height. * @return the transformed shape */ public static Shape transformShape(final Shape s, final boolean scale, final boolean keepAR, final double width, final double height) { /** * Always scale to the maximum bounds ... */ if (scale) { final Rectangle2D boundsShape = s.getBounds2D(); final double w = boundsShape.getWidth(); final double h = boundsShape.getHeight(); double scaleX = 1; if (w != 0) { scaleX = width / w; } double scaleY = 1; if (h != 0) { scaleY = height / h; } if (scaleX != 1 || scaleY != 1) { if (s instanceof RectangularShape) { return ShapeTransform.resizeRect((RectangularShape) s, w * scaleX, h * scaleY); } if (s instanceof Line2D) { return ShapeTransform.resizeLine((Line2D) s, w * scaleX, h * scaleY); } if (keepAR) { final double scaleFact = Math.min(scaleX, scaleY); return performDefaultTransformation(s, scaleFact, scaleFact); } else { return performDefaultTransformation(s, scaleX, scaleY); } } } return s; } /** * Translates the given shape. The shape is translated to the origin supplied * inpoint
. If scaling is requested, the shape will also be * scaled using an AffineTransform. * * @param s * the shape that should be transformed * @param scale * true, if the shape should be scaled, false otherwise * @param keepAR * true, if the scaled shape should keep the aspect ratio * @param dim * the target dimension. * @return the transformed shape */ public static Shape transformShape(final Shape s, final boolean scale, final boolean keepAR, final Dimension2D dim) { return transformShape(s, scale, keepAR, dim.getWidth(), dim.getHeight()); } /** * Clips the given shape to the given bounds. If the shape is a Line2D, manual * clipping is performed, as the built in Area does not handle lines. * * @param s * the shape to be clipped * @param bounds * the bounds to which the shape should be clipped * @return the clipped shape. */ public static Shape performCliping(final Shape s, final Rectangle2D bounds) { if (s instanceof Line2D) { final Line2D line = (Line2D) s; final Point2D[] clipped = getClipped(line.getX1(), line.getY1(), line.getX2(), line.getY2(), -DELTA, DELTA + bounds.getWidth(), -DELTA, DELTA + bounds.getHeight()); if (clipped == null) { return new GeneralPath(); } return new Line2D.Float(clipped[0], clipped[1]); } final Rectangle2D boundsCorrected = bounds.getBounds2D(); boundsCorrected.setRect(-DELTA, -DELTA, DELTA + boundsCorrected.getWidth(), DELTA + boundsCorrected.getHeight()); final Area a = new Area(boundsCorrected); if (a.isEmpty()) { // don"t clip ... Area does not like lines // operations with lines always result in an empty Bounds:(0,0,0,0) area return new GeneralPath(); } final Area clipArea = new Area(s); a.intersect(clipArea); return a; } /** * Scales a given shape. The shape is first normalized, then scaled and * finally brought back into its original position. * * @param shape * the shape to be scaled * @param scaleX * the horizontal scaling factor * @param scaleY * the vertical scaling factor * @return the scaled shape */ private static Shape performDefaultTransformation(final Shape shape, final double scaleX, final double scaleY) { /** * Apply the normalisation shape transform ... bring the shape to pos (0,0) */ final Rectangle2D bounds = shape.getBounds2D(); AffineTransform af = AffineTransform.getTranslateInstance(0 - bounds.getX(), 0 - bounds.getY()); // apply normalisation translation ... Shape s = af.createTransformedShape(shape); af = AffineTransform.getScaleInstance(scaleX, scaleY); // apply scaling ... s = af.createTransformedShape(s); // now retranslate the shape to its original position ... af = AffineTransform.getTranslateInstance(bounds.getX(), bounds.getY()); return af.createTransformedShape(s); } /** * Translates a given shape. Special care is taken to preserve the shape"s * original class, if the shape is a rectangle or a line. * * @param s * the shape * @param x * the x coordinate where the shape is translated to * @param y * the y coordinate where the shape is translated to * @return the translated shape */ public static Shape translateShape(final Shape s, final double x, final double y) { if (s instanceof RectangularShape) { final RectangularShape rect = (RectangularShape) s; final RectangularShape retval = (RectangularShape) rect.clone(); retval.setFrame(retval.getX() + x, retval.getY() + y, retval.getWidth(), retval.getHeight()); return retval; } if (s instanceof Line2D) { final Line2D line = (Line2D) s; final Line2D retval = (Line2D) line.clone(); retval .setLine(retval.getX1() + x, retval.getY1() + y, retval.getX2() + x, retval.getY2() + y); return retval; } final AffineTransform af = AffineTransform.getTranslateInstance(x, y); return af.createTransformedShape(s); } /** * Calculate the clipping points of a line with a rectangle. * * @param x1 * starting x of line * @param y1 * starting y of line * @param x2 * ending x of line * @param y2 * ending y of line * @param xmin * lower left x of rectangle * @param xmax * upper right x of rectangle * @param ymin * lower left y of rectangle * @param ymax * upper right y of rectangle * @returnnull
(does not clip) or array of two points */ public static Point2D[] getClipped(final double x1, final double y1, final double x2, final double y2, final double xmin, final double xmax, final double ymin, final double ymax) { int mask1 = 0; // position mask for first point if (x1 < xmin) { mask1 |= LEFT; } else if (x1 > xmax) { mask1 |= RIGHT; } else { mask1 |= H_CENTER; } if (y1 < ymin) { // btw: I know that in AWT y runs from down but I more used to // y pointing up and it makes no difference for the algorithms mask1 |= BELOW; } else if (y1 > ymax) { mask1 |= ABOVE; } else { mask1 |= V_CENTER; } int mask2 = 0; // position mask for second point if (x2 < xmin) { mask2 |= LEFT; } else if (x2 > xmax) { mask2 |= RIGHT; } else { mask2 |= H_CENTER; } if (y2 < ymin) { mask2 |= BELOW; } else if (y2 > ymax) { mask2 |= ABOVE; } else { mask2 |= V_CENTER; } final int mask = mask1 | mask2; if ((mask & OUTSIDE) == 0) { // fine. everything"s internal final Point2D[] ret = new Point2D[2]; ret[0] = new Point2D.Double(x1, y1); ret[1] = new Point2D.Double(x2, y2); return ret; } else if ((mask & (H_CENTER | LEFT)) == 0 || // everything"s right (mask & (H_CENTER | RIGHT)) == 0 || // everything"s left (mask & (V_CENTER | BELOW)) == 0 || // everything"s above (mask & (V_CENTER | ABOVE)) == 0) { // everything"s below // nothing to do return null; } else { // need clipping return getClipped(x1, y1, mask1, x2, y2, mask2, xmin, xmax, ymin, ymax); } } /** * Calculate the clipping points of a line with a rectangle. * * @param x1 * starting x of line * @param y1 * starting y of line * @param mask1 * clipping info mask for starting point * @param x2 * ending x of line * @param y2 * ending y of line * @param mask2 * clipping info mask for ending point * @param xmin * lower left x of rectangle * @param ymin * lower left y of rectangle * @param xmax * upper right x of rectangle * @param ymax * upper right y of rectangle * @returnnull
(does not clip) or array of two points */ private static Point2D[] getClipped(final double x1, final double y1, final int mask1, final double x2, final double y2, final int mask2, final double xmin, final double xmax, final double ymin, final double ymax) { final int mask = mask1 ^ mask2; Point2D p1 = null; if (mask1 == INSIDE) { // point 1 is internal p1 = new Point2D.Double(x1, y1); if (mask == 0) { // both masks are the same, so the second point is inside, too final Point2D[] ret = new Point2D[2]; ret[0] = p1; ret[1] = new Point2D.Double(x2, y2); return ret; } } else if (mask2 == INSIDE) { // point 2 is internal p1 = new Point2D.Double(x2, y2); } if ((mask & LEFT) != 0) { // System.out.println("Trying left"); // try to calculate intersection with left line final Point2D p = intersect(x1, y1, x2, y2, xmin, ymin, xmin, ymax); if (p != null) { if (p1 == null) { p1 = p; } else { final Point2D[] ret = new Point2D[2]; ret[0] = p1; ret[1] = p; return ret; } } } if ((mask & RIGHT) != 0) { // System.out.println("Trying right"); // try to calculate intersection with left line final Point2D p = intersect(x1, y1, x2, y2, xmax, ymin, xmax, ymax); if (p != null) { if (p1 == null) { p1 = p; } else { final Point2D[] ret = new Point2D[2]; ret[0] = p1; ret[1] = p; return ret; } } } if (mask1 == (LEFT | BELOW) || mask1 == (RIGHT | BELOW)) { // for exactly these two special cases use different sequence! if ((mask & ABOVE) != 0) { // System.out.println("Trying top"); // try to calculate intersection with lower line final Point2D p = intersect(x1, y1, x2, y2, xmin, ymax, xmax, ymax); if (p != null) { if (p1 == null) { p1 = p; } else { final Point2D[] ret = new Point2D[2]; ret[0] = p1; ret[1] = p; return ret; } } } if ((mask & BELOW) != 0) { // System.out.println("Trying bottom"); // try to calculate intersection with lower line final Point2D p = intersect(x1, y1, x2, y2, xmin, ymin, xmax, ymin); if (p != null && p1 != null) { final Point2D[] ret = new Point2D[2]; ret[0] = p1; ret[1] = p; return ret; } } } else { if ((mask & BELOW) != 0) { // System.out.println("Trying bottom"); // try to calculate intersection with lower line final Point2D p = intersect(x1, y1, x2, y2, xmin, ymin, xmax, ymin); if (p != null) { if (p1 == null) { p1 = p; } else { final Point2D[] ret = new Point2D[2]; ret[0] = p1; ret[1] = p; return ret; } } } if ((mask & ABOVE) != 0) { // System.out.println("Trying top"); // try to calculate intersection with lower line final Point2D p = intersect(x1, y1, x2, y2, xmin, ymax, xmax, ymax); if (p != null && p1 != null) { final Point2D[] ret = new Point2D[2]; ret[0] = p1; ret[1] = p; return ret; } } } // no (or not enough) intersections found return null; } /** * Intersect two lines. * * @param x11 * starting x of 1st line * @param y11 * starting y of 1st line * @param x12 * ending x of 1st line * @param y12 * ending y of 1st line * @param x21 * starting x of 2nd line * @param y21 * starting y of 2nd line * @param x22 * ending x of 2nd line * @param y22 * ending y of 2nd line * @return intersection point ornull
*/ private static Point2D intersect(final double x11, final double y11, final double x12, final double y12, final double x21, final double y21, final double x22, final double y22) { final double dx1 = x12 - x11; final double dy1 = y12 - y11; final double dx2 = x22 - x21; final double dy2 = y22 - y21; final double det = (dx2 * dy1 - dy2 * dx1); if (det != 0.0) { final double mu = ((x11 - x21) * dy1 - (y11 - y21) * dx1) / det; if (mu >= 0.0 && mu <= 1.0) { return new Point2D.Double(x21 + mu * dx2, y21 + mu * dy2); } } return null; }
}
</source>
Rotates a shape about the specified coordinates.
<source lang="java"> /*
* JCommon : a free general purpose class library for the Java(tm) platform * * * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jcommon/index.html * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * ------------------- * ShapeUtilities.java * ------------------- * (C)opyright 2003-2008, by Object Refinery Limited and Contributors. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): -; * * $Id: ShapeUtilities.java,v 1.18 2008/06/02 06:58:28 mungady Exp $ * * Changes * ------- * 13-Aug-2003 : Version 1 (DG); * 16-Mar-2004 : Moved rotateShape() from RefineryUtilities.java to here (DG); * 13-May-2004 : Added new shape creation methods (DG); * 30-Sep-2004 : Added createLineRegion() method (DG); * Moved drawRotatedShape() method from RefineryUtilities class * to this class (DG); * 04-Oct-2004 : Renamed ShapeUtils --> ShapeUtilities (DG); * 26-Oct-2004 : Added a method to test the equality of two Line2D * instances (DG); * 10-Nov-2004 : Added new translateShape() and equal(Ellipse2D, Ellipse2D) * methods (DG); * 11-Nov-2004 : Renamed translateShape() --> createTranslatedShape() (DG); * 07-Jan-2005 : Minor Javadoc fix (DG); * 11-Jan-2005 : Removed deprecated code in preparation for 1.0.0 release (DG); * 21-Jan-2005 : Modified return type of RectangleAnchor.coordinates() * method (DG); * 22-Feb-2005 : Added equality tests for Arc2D and GeneralPath (DG); * 16-Mar-2005 : Fixed bug where equal(Shape, Shape) fails for two Polygon * instances (DG); * 01-Jun-2008 : Fixed bug in equal(GeneralPath, GeneralPath) method (DG); * */
import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; /**
* Utility methods for {@link Shape} objects. * * @author David Gilbert */
public class Main {
/** * Rotates a shape about the specified coordinates. * * @param base the shape (null
permitted, returns *null
). * @param angle the angle (in radians). * @param x the x coordinate for the rotation point (in Java2D space). * @param y the y coordinate for the rotation point (in Java2D space). * * @return the rotated shape. */ public static Shape rotateShape(final Shape base, final double angle, final float x, final float y) { if (base == null) { return null; } final AffineTransform rotate = AffineTransform.getRotateInstance( angle, x, y); final Shape result = rotate.createTransformedShape(base); return result; }
}
</source>
Rotating a Drawn Image
<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; public class BasicDraw {
public static void main(String[] args) { JFrame frame = new JFrame(); frame.add(new MyComponent()); frame.setSize(300, 300); frame.setVisible(true); }
} class MyComponent extends JComponent {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; AffineTransform tx = new AffineTransform(); double radians = -Math.PI / 4; tx.rotate(radians); g2d.setTransform(tx); g2d.drawImage(new ImageIcon("a.png").getImage(), tx, this); }
}
</source>
Rotating a Shape with AffineTransform
<source lang="java">
import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; public class BasicShapes {
public static void main(String[] args) { AffineTransform tx = new AffineTransform(); tx.rotate(0.5); Rectangle shape = new Rectangle(1, 1, 1, 1); Shape newShape = tx.createTransformedShape(shape); }
}
</source>
Rotating image using Java 2D AffineTransform class
<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import javax.swing.JPanel; class ImagePanel extends JPanel {
int offset = 5; private Image image; private int angle; private int w, h; private AffineTransform transform; public ImagePanel(Image i) { image = i; w = image.getWidth(this); h = image.getHeight(this); transform = new AffineTransform(); } public void paintComponent(Graphics grp) { Rectangle rect = this.getBounds(); Graphics2D g2d = (Graphics2D) grp; transform.setToTranslation((rect.width - w) / 2, (rect.height - h) / 2); transform.rotate(Math.toRadians(angle), w / 2, h / 2); g2d.drawImage(image, transform, this); } public void rotate() { angle -= offset; if (angle <= 0) { angle = 360; } repaint(); }
}
</source>
Rotation and coordinate translation
<source lang="java"> import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; import javax.swing.JPanel; public class Rotate extends JPanel {
public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(new Color(150, 150, 150)); g2d.fillRect(20, 20, 80, 50); g2d.translate(180, -150); g2d.rotate(Math.PI / 4); g2d.fillRect(20, 20, 80, 50); } public static void main(String[] args) { JFrame frame = new JFrame("Rotation"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new Rotate()); frame.setSize(300, 200); frame.setVisible(true); }
}
</source>
Scaling a Drawn Image
<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; public class BasicDraw {
public static void main(String[] args) { JFrame frame = new JFrame(); frame.add(new MyComponent()); frame.setSize(300, 300); frame.setVisible(true); }
} class MyComponent extends JComponent {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; AffineTransform tx = new AffineTransform(); double scalex = .5; double scaley = 1; tx.scale(scalex, scaley); g2d.setTransform(tx); g2d.drawImage(new ImageIcon("a.png").getImage(), tx, this); }
}
</source>
Scaling an object
<source lang="java"> import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import javax.swing.JFrame; import javax.swing.JPanel; public class Scale extends JPanel {
public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(new Color(150, 150, 150)); g2d.fillRect(0, 0, 80, 50); AffineTransform tx1 = new AffineTransform(); tx1.translate(110, 20); tx1.scale(0.5, 0.5); g2d.setTransform(tx1); g2d.fillRect(0, 0, 80, 50); AffineTransform tx2 = new AffineTransform(); tx2.translate(200, 20); tx2.scale(1.5, 1.5); g2d.setTransform(tx2); g2d.fillRect(0, 0, 80, 50); } public static void main(String[] args) { JFrame frame = new JFrame("Scaling"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new Scale()); frame.setSize(330, 160); frame.setLocationRelativeTo(null); frame.setVisible(true); }
}
</source>
Scaling a Shape with AffineTransform
<source lang="java"> import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; public class BasicShapes {
public static void main(String[] args) { AffineTransform tx = new AffineTransform(); tx.scale(1, 1); Rectangle shape = new Rectangle(1, 1, 1, 1); Shape newShape = tx.createTransformedShape(shape); }
}
</source>
Shearing a Drawn Image
<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; public class BasicDraw {
public static void main(String[] args) { JFrame frame = new JFrame(); frame.add(new MyComponent()); frame.setSize(300, 300); frame.setVisible(true); }
} class MyComponent extends JComponent {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; AffineTransform tx = new AffineTransform(); double shiftx = .1; double shifty = .3; tx.shear(shiftx, shifty); g2d.setTransform(tx); g2d.drawImage(new ImageIcon("a.png").getImage(), tx, this); }
}
</source>
Shearing a Shape with AffineTransform
<source lang="java"> import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; public class BasicShapes {
public static void main(String[] args) { AffineTransform tx = new AffineTransform(); tx.shear(1, 1); Rectangle shape = new Rectangle(1, 1, 1, 1); Shape newShape = tx.createTransformedShape(shape); }
}
</source>
Transform Demo
<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.TexturePaint; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import javax.swing.JFrame; import javax.swing.JPanel; public class TransformDemo extends JPanel {
public void init() { setBackground(Color.white); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; Rectangle rect = new Rectangle(5,5,200,200); int w = getSize().width; int h = getSize().height; AffineTransform saveXform = g2.getTransform(); AffineTransform toCenterAt = new AffineTransform(); toCenterAt.translate(w / 2 - (rect.width / 2), h / 2 - (rect.height / 2)); g2.transform(toCenterAt); g2.fill(rect); g2.transform(saveXform); } public static void main(String s[]) { JFrame f = new JFrame(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); TransformDemo p = new TransformDemo(); f.getContentPane().add("Center", p); p.init(); f.pack(); f.setSize(new Dimension(300, 300)); f.show(); }
}
</source>
Transforme Rotation demo
<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class TransformersRotation extends JComponent {
Shape axes, shape; int length = 54, arrowLength = 4, tickSize = 4; public TransformersRotation() { axes = createAxes(); shape = createShape(); } protected Shape createAxes() { GeneralPath path = new GeneralPath(); // Axes. path.moveTo(-length, 0); path.lineTo(length, 0); path.moveTo(0, -length); path.lineTo(0, length); // Arrows. path.moveTo(length - arrowLength, -arrowLength); path.lineTo(length, 0); path.lineTo(length - arrowLength, arrowLength); path.moveTo(-arrowLength, length - arrowLength); path.lineTo(0, length); path.lineTo(arrowLength, length - arrowLength); // Half-centimeter tick marks float cm = 72 / 2.54f; float lengthCentimeter = length / cm; for (float i = 0.5f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize / 2); path.lineTo(tick, tickSize / 2); path.moveTo(-tick, -tickSize / 2); path.lineTo(-tick, tickSize / 2); path.moveTo(-tickSize / 2, tick); path.lineTo(tickSize / 2, tick); path.moveTo(-tickSize / 2, -tick); path.lineTo(tickSize / 2, -tick); } // Full-centimeter tick marks for (float i = 1.0f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize); path.lineTo(tick, tickSize); path.moveTo(-tick, -tickSize); path.lineTo(-tick, tickSize); path.moveTo(-tickSize, tick); path.lineTo(tickSize, tick); path.moveTo(-tickSize, -tick); path.lineTo(tickSize, -tick); } return path; } protected Shape createShape() { float cm = 72 / 2.54f; return new Rectangle2D.Float(cm, cm, 2 * cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // Use antialiasing. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Move the origin to 75, 75. AffineTransform at = AffineTransform.getTranslateInstance(75, 75); g2.transform(at); // Draw the shapes in their original locations. g2.setPaint(Color.black); g2.draw(axes); g2.draw(shape); // Transform the Graphics2D. g2.transform(AffineTransform.getRotateInstance(-Math.PI / 6)); // Draw the "new" shapes in dashed. Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3, 1 }, 0); g2.setStroke(stroke); g2.draw(axes); g2.draw(shape); } public static void main(String[] a) { JFrame f = new JFrame(); f.getContentPane().add(new TransformersRotation()); f.setSize(350, 200); f.show(); }
}
</source>
Transform Rotation Translation
<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class TransformersRotationTranslation extends JComponent {
Shape axes, shape; int length = 54, arrowLength = 4, tickSize = 4; public TransformersRotationTranslation() { axes = createAxes(); shape = createShape(); } protected Shape createAxes() { GeneralPath path = new GeneralPath(); // Axes. path.moveTo(-length, 0); path.lineTo(length, 0); path.moveTo(0, -length); path.lineTo(0, length); // Arrows. path.moveTo(length - arrowLength, -arrowLength); path.lineTo(length, 0); path.lineTo(length - arrowLength, arrowLength); path.moveTo(-arrowLength, length - arrowLength); path.lineTo(0, length); path.lineTo(arrowLength, length - arrowLength); // Half-centimeter tick marks float cm = 72 / 2.54f; float lengthCentimeter = length / cm; for (float i = 0.5f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize / 2); path.lineTo(tick, tickSize / 2); path.moveTo(-tick, -tickSize / 2); path.lineTo(-tick, tickSize / 2); path.moveTo(-tickSize / 2, tick); path.lineTo(tickSize / 2, tick); path.moveTo(-tickSize / 2, -tick); path.lineTo(tickSize / 2, -tick); } // Full-centimeter tick marks for (float i = 1.0f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize); path.lineTo(tick, tickSize); path.moveTo(-tick, -tickSize); path.lineTo(-tick, tickSize); path.moveTo(-tickSize, tick); path.lineTo(tickSize, tick); path.moveTo(-tickSize, -tick); path.lineTo(tickSize, -tick); } return path; } protected Shape createShape() { float cm = 72 / 2.54f; return new Rectangle2D.Float(cm, cm, 2 * cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // Use antialiasing. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Move the origin to 75, 75. AffineTransform at = AffineTransform.getTranslateInstance(75, 75); g2.transform(at); // Draw the shapes in their original locations. g2.setPaint(Color.black); g2.draw(axes); g2.draw(shape); // Transform the Graphics2D. AffineTransform rat = new AffineTransform(); rat.setToRotation(Math.PI / 6); rat.translate(100, 100); g2.transform(rat); // Draw the "new" shapes in dashed. Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3, 1 }, 0); g2.setStroke(stroke); g2.draw(axes); g2.draw(shape); } public static void main(String[] a) { JFrame f = new JFrame(); f.getContentPane().add(new TransformersRotationTranslation()); f.setSize(350, 450); f.show(); }
}
</source>
Transform Scale
<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class TransformScale extends JComponent {
Shape axes, shape; int length = 54, arrowLength = 4, tickSize = 4; public TransformScale() { axes = createAxes(); shape = createShape(); } protected Shape createAxes() { GeneralPath path = new GeneralPath(); // Axes. path.moveTo(-length, 0); path.lineTo(length, 0); path.moveTo(0, -length); path.lineTo(0, length); // Arrows. path.moveTo(length - arrowLength, -arrowLength); path.lineTo(length, 0); path.lineTo(length - arrowLength, arrowLength); path.moveTo(-arrowLength, length - arrowLength); path.lineTo(0, length); path.lineTo(arrowLength, length - arrowLength); // Half-centimeter tick marks float cm = 72 / 2.54f; float lengthCentimeter = length / cm; for (float i = 0.5f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize / 2); path.lineTo(tick, tickSize / 2); path.moveTo(-tick, -tickSize / 2); path.lineTo(-tick, tickSize / 2); path.moveTo(-tickSize / 2, tick); path.lineTo(tickSize / 2, tick); path.moveTo(-tickSize / 2, -tick); path.lineTo(tickSize / 2, -tick); } // Full-centimeter tick marks for (float i = 1.0f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize); path.lineTo(tick, tickSize); path.moveTo(-tick, -tickSize); path.lineTo(-tick, tickSize); path.moveTo(-tickSize, tick); path.lineTo(tickSize, tick); path.moveTo(-tickSize, -tick); path.lineTo(tickSize, -tick); } return path; } protected Shape createShape() { float cm = 72 / 2.54f; return new Rectangle2D.Float(cm, cm, 2 * cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // Use antialiasing. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Move the origin to 75, 75. AffineTransform at = AffineTransform.getTranslateInstance(75, 75); g2.transform(at); // Draw the shapes in their original locations. g2.setPaint(Color.black); g2.draw(axes); g2.draw(shape); // Transform the Graphics2D. g2.transform(AffineTransform.getScaleInstance(3, 3)); // Draw the "new" shapes in dashed. g2.transform(AffineTransform.getTranslateInstance(75, 75)); Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3, 1 }, 0); g2.setStroke(stroke); g2.draw(axes); g2.draw(shape); } public static void main(String[] a) { JFrame f = new JFrame(); f.getContentPane().add(new TransformScale()); f.setSize(650, 550); f.show(); }
}
</source>
Transform Shear
<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class TransformShear extends JComponent {
Shape axes, shape; int length = 54, arrowLength = 4, tickSize = 4; public TransformShear() { axes = createAxes(); shape = createShape(); } protected Shape createAxes() { GeneralPath path = new GeneralPath(); // Axes. path.moveTo(-length, 0); path.lineTo(length, 0); path.moveTo(0, -length); path.lineTo(0, length); // Arrows. path.moveTo(length - arrowLength, -arrowLength); path.lineTo(length, 0); path.lineTo(length - arrowLength, arrowLength); path.moveTo(-arrowLength, length - arrowLength); path.lineTo(0, length); path.lineTo(arrowLength, length - arrowLength); // Half-centimeter tick marks float cm = 72 / 2.54f; float lengthCentimeter = length / cm; for (float i = 0.5f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize / 2); path.lineTo(tick, tickSize / 2); path.moveTo(-tick, -tickSize / 2); path.lineTo(-tick, tickSize / 2); path.moveTo(-tickSize / 2, tick); path.lineTo(tickSize / 2, tick); path.moveTo(-tickSize / 2, -tick); path.lineTo(tickSize / 2, -tick); } // Full-centimeter tick marks for (float i = 1.0f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize); path.lineTo(tick, tickSize); path.moveTo(-tick, -tickSize); path.lineTo(-tick, tickSize); path.moveTo(-tickSize, tick); path.lineTo(tickSize, tick); path.moveTo(-tickSize, -tick); path.lineTo(tickSize, -tick); } return path; } protected Shape createShape() { float cm = 72 / 2.54f; return new Rectangle2D.Float(cm, cm, 2 * cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // Use antialiasing. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Move the origin to 75, 75. AffineTransform at = AffineTransform.getTranslateInstance(75, 75); g2.transform(at); // Draw the shapes in their original locations. g2.setPaint(Color.black); g2.draw(axes); g2.draw(shape); // Transform the Graphics2D. AffineTransform sat = AffineTransform.getTranslateInstance(150, 0); sat.shear(-.5, 0); g2.transform(sat); // Draw the "new" shapes in dashed. g2.transform(AffineTransform.getTranslateInstance(75, 75)); Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3, 1 }, 0); g2.setStroke(stroke); g2.draw(axes); g2.draw(shape); } public static void main(String[] a) { JFrame f = new JFrame(); f.getContentPane().add(new TransformShear()); f.setSize(450, 350); f.show(); }
}
</source>
Transform Translated Rotation
<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class TransformTranslatedRotation extends JComponent {
Shape axes, shape; int length = 54, arrowLength = 4, tickSize = 4; public TransformTranslatedRotation() { axes = createAxes(); shape = createShape(); } protected Shape createAxes() { GeneralPath path = new GeneralPath(); // Axes. path.moveTo(-length, 0); path.lineTo(length, 0); path.moveTo(0, -length); path.lineTo(0, length); // Arrows. path.moveTo(length - arrowLength, -arrowLength); path.lineTo(length, 0); path.lineTo(length - arrowLength, arrowLength); path.moveTo(-arrowLength, length - arrowLength); path.lineTo(0, length); path.lineTo(arrowLength, length - arrowLength); // Half-centimeter tick marks float cm = 72 / 2.54f; float lengthCentimeter = length / cm; for (float i = 0.5f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize / 2); path.lineTo(tick, tickSize / 2); path.moveTo(-tick, -tickSize / 2); path.lineTo(-tick, tickSize / 2); path.moveTo(-tickSize / 2, tick); path.lineTo(tickSize / 2, tick); path.moveTo(-tickSize / 2, -tick); path.lineTo(tickSize / 2, -tick); } // Full-centimeter tick marks for (float i = 1.0f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize); path.lineTo(tick, tickSize); path.moveTo(-tick, -tickSize); path.lineTo(-tick, tickSize); path.moveTo(-tickSize, tick); path.lineTo(tickSize, tick); path.moveTo(-tickSize, -tick); path.lineTo(tickSize, -tick); } return path; } protected Shape createShape() { float cm = 72 / 2.54f; return new Rectangle2D.Float(cm, cm, 2 * cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // Use antialiasing. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Move the origin to 75, 75. AffineTransform at = AffineTransform.getTranslateInstance(75, 75); g2.transform(at); // Draw the shapes in their original locations. g2.setPaint(Color.black); g2.draw(axes); g2.draw(shape); // Transform the Graphics2D. float cm = 72 / 2.54f; g2.transform(AffineTransform.getRotateInstance(-Math.PI / 6, 3 * cm, 2 * cm)); // Draw the "new" shapes in dashed. Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3, 1 }, 0); g2.setStroke(stroke); g2.draw(axes); g2.draw(shape); } public static void main(String[] a) { JFrame f = new JFrame(); f.getContentPane().add(new TransformTranslatedRotation()); f.setSize(450, 350); f.show(); }
}
</source>
Transform Translation
<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class TransformTranslation extends JComponent {
Shape axes, shape; int length = 54, arrowLength = 4, tickSize = 4; public TransformTranslation() { axes = createAxes(); shape = createShape(); } protected Shape createAxes() { GeneralPath path = new GeneralPath(); // Axes. path.moveTo(-length, 0); path.lineTo(length, 0); path.moveTo(0, -length); path.lineTo(0, length); // Arrows. path.moveTo(length - arrowLength, -arrowLength); path.lineTo(length, 0); path.lineTo(length - arrowLength, arrowLength); path.moveTo(-arrowLength, length - arrowLength); path.lineTo(0, length); path.lineTo(arrowLength, length - arrowLength); // Half-centimeter tick marks float cm = 72 / 2.54f; float lengthCentimeter = length / cm; for (float i = 0.5f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize / 2); path.lineTo(tick, tickSize / 2); path.moveTo(-tick, -tickSize / 2); path.lineTo(-tick, tickSize / 2); path.moveTo(-tickSize / 2, tick); path.lineTo(tickSize / 2, tick); path.moveTo(-tickSize / 2, -tick); path.lineTo(tickSize / 2, -tick); } // Full-centimeter tick marks for (float i = 1.0f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize); path.lineTo(tick, tickSize); path.moveTo(-tick, -tickSize); path.lineTo(-tick, tickSize); path.moveTo(-tickSize, tick); path.lineTo(tickSize, tick); path.moveTo(-tickSize, -tick); path.lineTo(tickSize, -tick); } return path; } protected Shape createShape() { float cm = 72 / 2.54f; return new Rectangle2D.Float(cm, cm, 2 * cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // Use antialiasing. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Move the origin to 75, 75. AffineTransform at = AffineTransform.getTranslateInstance(75, 75); g2.transform(at); // Draw the shapes in their original locations. g2.setPaint(Color.black); g2.draw(axes); g2.draw(shape); // Transform the Graphics2D. g2.transform(AffineTransform.getTranslateInstance(150, 0)); // Draw the "new" shapes in dashed. Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3, 1 }, 0); g2.setStroke(stroke); g2.draw(axes); g2.draw(shape); } public static void main(String[] a) { JFrame f = new JFrame(); f.getContentPane().add(new TransformTranslation()); f.setSize(450, 350); f.show(); }
}
</source>
Transform Translation and Rotation
<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class TransformTransRotation extends JComponent {
Shape axes, shape; int length = 54, arrowLength = 4, tickSize = 4; public TransformTransRotation() { axes = createAxes(); shape = createShape(); } protected Shape createAxes() { GeneralPath path = new GeneralPath(); // Axes. path.moveTo(-length, 0); path.lineTo(length, 0); path.moveTo(0, -length); path.lineTo(0, length); // Arrows. path.moveTo(length - arrowLength, -arrowLength); path.lineTo(length, 0); path.lineTo(length - arrowLength, arrowLength); path.moveTo(-arrowLength, length - arrowLength); path.lineTo(0, length); path.lineTo(arrowLength, length - arrowLength); // Half-centimeter tick marks float cm = 72 / 2.54f; float lengthCentimeter = length / cm; for (float i = 0.5f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize / 2); path.lineTo(tick, tickSize / 2); path.moveTo(-tick, -tickSize / 2); path.lineTo(-tick, tickSize / 2); path.moveTo(-tickSize / 2, tick); path.lineTo(tickSize / 2, tick); path.moveTo(-tickSize / 2, -tick); path.lineTo(tickSize / 2, -tick); } // Full-centimeter tick marks for (float i = 1.0f; i < lengthCentimeter; i += 1.0f) { float tick = i * cm; path.moveTo(tick, -tickSize); path.lineTo(tick, tickSize); path.moveTo(-tick, -tickSize); path.lineTo(-tick, tickSize); path.moveTo(-tickSize, tick); path.lineTo(tickSize, tick); path.moveTo(-tickSize, -tick); path.lineTo(tickSize, -tick); } return path; } protected Shape createShape() { float cm = 72 / 2.54f; return new Rectangle2D.Float(cm, cm, 2 * cm, cm); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // Use antialiasing. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Move the origin to 75, 75. AffineTransform at = AffineTransform.getTranslateInstance(75, 75); g2.transform(at); // Draw the shapes in their original locations. g2.setPaint(Color.black); g2.draw(axes); g2.draw(shape); // Transform the Graphics2D. AffineTransform rat = new AffineTransform(); rat.setToTranslation(100, 0); rat.rotate(Math.PI / 6); g2.transform(rat); // Draw the "new" shapes in dashed. Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] { 3, 1 }, 0); g2.setStroke(stroke); g2.draw(axes); g2.draw(shape); } public static void main(String[] a) { JFrame f = new JFrame(); f.getContentPane().add(new TransformTransRotation()); f.setSize(450, 350); f.show(); }
}
</source>
Translating a Drawn Image
<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; public class BasicDraw {
public static void main(String[] args) { JFrame frame = new JFrame(); frame.add(new MyComponent()); frame.setSize(300, 300); frame.setVisible(true); }
} class MyComponent extends JComponent {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; AffineTransform tx = new AffineTransform(); double x = 50; double y = 50; tx.translate(x, y); g2d.setTransform(tx); g2d.drawImage(new ImageIcon("a.png").getImage(), tx, this); }
}
</source>
Translating a Shape with AffineTransform
<source lang="java"> import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; public class BasicShapes {
public static void main(String[] args) { AffineTransform tx = new AffineTransform(); tx.translate(1, 10); Rectangle shape = new Rectangle(1, 1, 1, 1); Shape newShape = tx.createTransformedShape(shape); }
}
</source>