Transformations
In this part of the Java 2D programming tutorial, we will talk about transformations.An affine transform is composed of zero or more linear transformations (rotation, scaling or shear) and translation (shift). Several linear transformations can be combined into a single matrix. A rotation is a transformation that moves a rigid body around a fixed point. A scaling is a transformation that enlarges or diminishes objects. The scale factor is the same in all directions. A translation is a transformation that moves every point a constant distance in a specified direction. A shear is a transformation that moves an object perpendicular to a given axis, with greater value on one side of the axis than the other. sources: (wikipedia.org, freedictionary.com)
The
AffineTransform
is the class in Java 2D to perform affine transformations. Translation
The following example describes a simple translation.Translation.java
package com.zetcode;The example draws a rectangle. Then we do a translation and draw the same rectangle again.
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.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
g2d.translate(150, 50);This line moves the origin of the Graphics2D context to a new point.
Figure: Translation
Rotation
The next example demonstrates a rotation.Rotate.java
package com.zetcode;The example draws a rectangle, performs a translation and a rotation and draws the same rectangle again.
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, -50);
g2d.rotate(Math.PI/4);
g2d.fillRect(80, 80, 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.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
g2d.rotate(Math.PI/4);The
rotate()
method performs rotation. Note that the rotation parameter is in radians. Figure: Rotation
Scale
The next example demonstrates scaling of an object. Scaling is done with thescale()
method. In this method, we provide two parameters. They are the x scale and y scale factor, by which coordinates are scaled along the x or y axis respectively Scale.java
package com.zetcode;We have a rectangle. First we scale it down and then we scale it up a bit.
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(20, 20, 80, 50);
AffineTransform tx1 = new AffineTransform();
tx1.translate(110, 22);
tx1.scale(0.5, 0.5);
g2d.setTransform(tx1);
g2d.fillRect(0, 0, 80, 50);
AffineTransform tx2 = new AffineTransform();
tx2.translate(170, 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);
}
}
AffineTransform tx2 = new AffineTransform();Another scaling would be added to the first one. So we need to create and apply another affine transform.
tx2.translate(170, 20);
tx2.scale(1.5, 1.5);
Figure: Scaling
Shearing
In the following example we perform shearing. We use theshare()
method. Scale.java
package com.zetcode;In this example, we draw three rectlangles in three different colors. They form a structure. Two of them are sheared.
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, 160, 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));
AffineTransform tx3 = new AffineTransform();
tx3.translate(130, 10);
tx3.shear(0, 1);
g2d.setTransform(tx3);
g2d.setColor(Color.red);
g2d.drawRect(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);
}
}
tx2.shear(0, 1);The two parameters are multipliers by which coordinates are shifted in the direction of the x and y axis.
Figure: Shearing
Donut
In the following example we create an complex shape by rotating an ellipse.Donut.java
package com.zetcode;In this example, we create a donut.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Donut extends JPanel {
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHints(rh);
Dimension size = getSize();
double w = size.getWidth();
double h = size.getHeight();
Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);
g2.setStroke(new BasicStroke(1));
g2.setColor(Color.gray);
for (double deg = 0; deg < 360; deg += 5) {
AffineTransform at =
AffineTransform.getTranslateInstance(w / 2, h / 2);
at.rotate(Math.toRadians(deg));
g2.draw(at.createTransformedShape(e));
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Donut");
frame.add(new Donut());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(370, 320);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);In the beginning there was an ellipse.
g2.setStroke(new BasicStroke(1));
g2.setColor(Color.gray);
for (double deg = 0; deg < 360; deg += 5) {After several rotations, there is a donut.
AffineTransform at =
AffineTransform.getTranslateInstance(w / 2, h / 2);
at.rotate(Math.toRadians(deg));
g2.draw(at.createTransformedShape(e));
}
Figure: Donut
In this part of the Java 2D tutorial, we have talked about transformations.
0 comments:
Post a Comment