Java Tutorial/2D Graphics/Tranformation
Содержание
- 1 Calculate Rotation Transform with Math.PI
- 2 Coordinate Translation.
- 3 Move and scale graphical objects with a mouse on the panel
- 4 Rotate a line of character (String)
- 5 Rotates a shape about the specified coordinates.
- 6 Rotating image using Java 2D AffineTransform class
- 7 Rotation and coordinate translation
- 8 Scaling an object
- 9 Tranformation with AffineTransform.getScaleInstance
- 10 Tranformation with AffineTransform.getShearInstance
- 11 Tranformation with AffineTransform.getTranslateInstance
- 12 Transform Lab
- 13 Translate and rotate all objects
Calculate Rotation Transform with Math.PI
<source lang="java">
import java.awt.Canvas; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Toolkit; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import javax.swing.JFrame; public class Draw2DRotate extends JFrame {
public static void main(String args[]) { Draw2DRotate app = new Draw2DRotate(); } public Draw2DRotate() { add("Center", new MyCanvas()); setSize(400, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); }
} class MyCanvas extends Canvas {
public void paint(Graphics graphics) { Graphics2D g = (Graphics2D) graphics; AffineTransform transform = AffineTransform.getRotateInstance(Math.PI / 16.0d); g.setTransform(transform); Line2D.Double shape = new Line2D.Double(0.0, 0.0, 300.0, 300.0); g.draw(shape); g.setFont(new Font("Helvetica", Font.BOLD, 24)); String text = ("jexp"); g.drawString(text, 300, 50); Toolkit toolkit = Toolkit.getDefaultToolkit(); Image image = toolkit.getImage("image1.gif"); g.drawImage(image, 100, 150, this); }
}</source>
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 Translation 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(150, 50); g2d.fillRect(20, 20, 80, 50); } public static void main(String[] args) { JFrame frame = new JFrame("Translation"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new Translation()); frame.setSize(300, 200); frame.setVisible(true); }
}</source>
Move and scale graphical objects with a mouse on the panel
<source lang="java">
import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.geom.Rectangle2D; import javax.swing.JFrame; import javax.swing.JPanel; public class MouseMoveScale extends JPanel {
private Rectangle2D.Float myRect = new Rectangle2D.Float(50, 50, 50, 50); MovingAdapter ma = new MovingAdapter(); public MouseMoveScale() { addMouseMotionListener(ma); addMouseListener(ma); addMouseWheelListener(new ScaleHandler()); } public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setColor(new Color(0, 0, 200)); g2d.fill(myRect); } class MovingAdapter extends MouseAdapter { private int x; private int y; public void mousePressed(MouseEvent e) { x = e.getX(); y = e.getY(); } public void mouseDragged(MouseEvent e) { int dx = e.getX() - x; int dy = e.getY() - y; if (myRect.getBounds2D().contains(x, y)) { myRect.x += dx; myRect.y += dy; repaint(); } x += dx; y += dy; } } class ScaleHandler implements MouseWheelListener { public void mouseWheelMoved(MouseWheelEvent e) { int x = e.getX(); int y = e.getY(); if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { if (myRect.getBounds2D().contains(x, y)) { float amount = e.getWheelRotation() * 5f; myRect.width += amount; myRect.height += amount; repaint(); } } } } public static void main(String[] args) { JFrame frame = new JFrame("Moving and Scaling"); MouseMoveScale m = new MouseMoveScale(); m.setDoubleBuffered(true); frame.add(m); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 300); frame.setLocationRelativeTo(null); frame.setVisible(true); }
}</source>
Rotate a line of character (String)
<source lang="java">
import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import javax.swing.JFrame; import javax.swing.JPanel; public class RotatedText extends JPanel {
public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); String s = "111111111111111111111111111111"; Font font = new Font("Courier", Font.PLAIN, 12); g2d.translate(20, 20); FontRenderContext frc = g2d.getFontRenderContext(); GlyphVector gv = font.createGlyphVector(frc, s); int length = gv.getNumGlyphs(); for (int i = 0; i < length; i++) { Point2D p = gv.getGlyphPosition(i); AffineTransform at = AffineTransform.getTranslateInstance(p.getX(), p.getY()); at.rotate((double) i / (double) (length - 1) * Math.PI / 3); Shape glyph = gv.getGlyphOutline(i); Shape transformedGlyph = at.createTransformedShape(glyph); g2d.fill(transformedGlyph); } } public static void main(String[] args) { JFrame frame = new JFrame("Rotated text"); frame.add(new RotatedText()); frame.setSize(400, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); }
}</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 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 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>
Tranformation with AffineTransform.getScaleInstance
<source lang="java">
import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; public class AffineTransformGetScaleInstance extends Frame {
public static void main(String[] args) { (new AffineTransformGetScaleInstance()).setVisible(true); } public AffineTransformGetScaleInstance() { setSize(350, 300); } public void paint(Graphics g) { AffineTransform atrans = null; Graphics2D g2d = (Graphics2D) g; atrans = AffineTransform.getScaleInstance(2, 3); if (atrans != null) g2d.setTransform(atrans); g2d.fillRect(50, 50, 100, 50); }
}</source>
Tranformation with AffineTransform.getShearInstance
<source lang="java">
import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; public class AffineTransformGetShearInstance extends Frame {
public static void main(String[] args) { (new AffineTransformGetShearInstance()).setVisible(true); } public AffineTransformGetShearInstance() { setSize(350, 300); } public void paint(Graphics g) { AffineTransform atrans = null; Graphics2D g2d = (Graphics2D) g; atrans = AffineTransform.getShearInstance(.1, .5); if (atrans != null) g2d.setTransform(atrans); g2d.fillRect(50, 50, 100, 50); }
}</source>
Tranformation with AffineTransform.getTranslateInstance
<source lang="java">
import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; public class AffineTransformGetTranslateInstance extends Frame {
public static void main(String[] args) { (new AffineTransformGetTranslateInstance()).setVisible(true); } public AffineTransformGetTranslateInstance() { setSize(350, 300); } public void paint(Graphics g) { AffineTransform atrans = null; Graphics2D g2d = (Graphics2D) g; atrans = AffineTransform.getTranslateInstance(50, 100); if (atrans != null) g2d.setTransform(atrans); g2d.fillRect(50, 50, 100, 50); }
}</source>
Transform Lab
<source lang="java">
import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; public class AffineTransformGetRotateInstance extends Frame {
public static void main(String[] args) { (new AffineTransformGetRotateInstance()).setVisible(true); } public AffineTransformGetRotateInstance() { setSize(350, 300); } public void paint(Graphics g) { AffineTransform atrans = null; Graphics2D g2d = (Graphics2D) g; atrans = AffineTransform.getRotateInstance(Math.PI / 4, 50, 50); if (atrans != null) g2d.setTransform(atrans); g2d.fillRect(50, 50, 100, 50); }
}</source>
Translate and rotate all objects
<source lang="java">
import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Toolkit; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.awt.geom.RoundRectangle2D; import javax.swing.JComponent; import javax.swing.JFrame; public class Main extends JComponent {
private Image image; private int theta; public Main() { image = Toolkit.getDefaultToolkit().getImage("A.jpg"); theta = 0; addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent me) { theta = (theta + 15) % 360; repaint(); } }); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int cx = getSize().width / 2; int cy = getSize().height / 2; g2.translate(cx, cy); g2.rotate(theta * Math.PI / 180); Shape oldClip = g2.getClip(); Shape e = new Ellipse2D.Float(-cx, -cy, cx * 2, cy * 2); g2.clip(e); Shape c = new Ellipse2D.Float(-cx, -cy, cx * 3 / 4, cy * 2); g2.setPaint(new GradientPaint(40, 40, Color.blue, 60, 50, Color.white, true)); g2.fill(c); g2.setPaint(Color.yellow); g2.fillOval(cx / 4, 0, cx, cy); g2.setClip(oldClip); g2.setFont(new Font("Times New Roman", Font.PLAIN, 64)); g2.setPaint(new GradientPaint(-cx, 0, Color.red, cx, 0, Color.black, false)); g2.drawString("Hello, 2D!", -cx * 3 / 4, cy / 4); AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) .75); g2.setComposite(ac); Shape r = new RoundRectangle2D.Float(0, -cy * 3 / 4, cx * 3 / 4, cy * 3 / 4, 20, 20); g2.setStroke(new BasicStroke(4)); g2.setPaint(Color.magenta); g2.fill(r); g2.setPaint(Color.green); g2.draw(r); g2.drawImage(image, -cx / 2, -cy / 2, this); } public static void main(String[] args) { JFrame frame = new JFrame(); frame.add(new Main(), BorderLayout.CENTER); frame.setSize(300, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }
}</source>