Clipping
In this part of the Java 2D tutorial, we will talk about clipping.Clipping
Clipping is restricting of drawing to a certain area. This is done for efficiency reasons and to create various effects.In the following example we will be clipping an image.
Clipping.java
package com.zetcode;In this example, we will clip an image. A circle is moving on the screen and showing a part of the underlying image. This is as if we looked through a hole.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Clipping extends JPanel implements ActionListener {
private int pos_x = 8;
private int pos_y = 8;
private int radius = 90;
Timer timer;
Image image;
private double delta[] = { 3, 3 };
public Clipping() {
image = new ImageIcon("bardejov.png").getImage();
timer = new Timer(15, this);
timer.start();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2d.setClip(new Ellipse2D.Double(pos_x, pos_y, radius, radius));
g2d.drawImage(image, 5, 5, null);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Clipping");
frame.add(new Clipping());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
int w = getWidth();
int h = getHeight();
if (pos_x < 0) {
delta[0] = Math.random() % 4 + 5;
} else if (pos_x > w - radius) {
delta[0] = -(Math.random() % 4 + 5);
}
if (pos_y < 0 ) {
delta[1] = Math.random() % 4 + 5;
} else if (pos_y > h - radius) {
delta[1] = -(Math.random() % 4 + 5);
}
pos_x += delta[0];
pos_y += delta[1];
repaint();
}
}
g2d.setClip(new Ellipse2D.Double(pos_x, pos_y, radius, radius));This is the key part of the code. Here we restrict drawing to a specific shape. In our case it is a circle.
if (pos_x < 0) {If the circle hits the left or the right side of the window, the direction of the circle movement changes randomly. Same for the top and bottom sides.
delta[0] = Math.random() % 4 + 5;
} else if (pos_x > w - radius) {
delta[0] = -(Math.random() % 4 + 5);
}
Figure: Clipping
Clipping shapes
In the following example, we will be clipping two shapes. A rectangle and a circle.ClippingShapes.java
package com.zetcode;In our example, we have a bouncing circle and a rotating rectangle. When these shapes overlap, the resulting area is filled with color.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ClippingShapes extends JPanel implements ActionListener {
private Timer timer;
private double rotate = 1;
private int pos_x = 8;
private int pos_y = 8;
private int radius = 60;
private double delta[] = { 1, 1 };
public ClippingShapes() {
timer = new Timer(10, this);
timer.start();
}
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_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
int w = getWidth();
int h = getHeight();
Rectangle rect1 = new Rectangle(0, 0, 200, 80);
AffineTransform tx = new AffineTransform();
tx.rotate(Math.toRadians(rotate), w / 2, h / 2);
tx.translate(w / 2 - 100, h / 2 - 40);
Ellipse2D circle = new Ellipse2D.Double(pos_x, pos_y, radius, radius);
step();
GeneralPath path = new GeneralPath();
path.append(tx.createTransformedShape(rect1), false);
g2d.setColor(new Color(110, 110, 110));
g2d.clip(circle);
g2d.clip(path);
g2d.fill(circle);
g2d.setClip(new Rectangle(0, 0, w, h));
g2d.draw(circle);
g2d.draw(path);
}
public void step() {
int w = getWidth();
int h = getHeight();
if (pos_x < 0) {
delta[0] = 1;
} else if (pos_x > w - radius) {
delta[0] = -1;
}
if (pos_y < 0) {
delta[1] = 1;
} else if (pos_y > h - radius) {
delta[1] = -1;
}
pos_x += delta[0];
pos_y += delta[1];
}
public static void main(String[] args) {
JFrame frame = new JFrame("Clipping shapes");
frame.add(new ClippingShapes());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(350, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
rotate += 1;
repaint();
}
}
Rectangle rect1 = new Rectangle(0, 0, 200, 80);The rectangle is being rotated. It is always positioned in the middle of the panel.
AffineTransform tx = new AffineTransform();
tx.rotate(Math.toRadians(rotate), w / 2, h / 2);
tx.translate(w / 2 - 100, h / 2 - 40);
GeneralPath path = new GeneralPath();Here we get the shape of the rotated rectangle.
path.append(tx.createTransformedShape(rect1), false);
g2d.clip(circle);Here we restrict drawing to these two shapes. If they overlap, the interior of the resulting shape is filled with color.
g2d.clip(path);
g2d.fill(circle)
g2d.setClip(new Rectangle(0, 0, w, h));We reset the clip areas, before we draw the shapes.
Figure: Clipping Shapes
In this part of the Java 2D tutorial, we have talked about clipping.
0 comments:
Post a Comment