You are here:Home » Java 2D » Clipping in Java 2D

Clipping in Java 2D

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;

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();
}
}
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.
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) {
delta[0] = Math.random() % 4 + 5;
} else if (pos_x > w - radius) {
delta[0] = -(Math.random() % 4 + 5);
}
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.
Clipping
Figure: Clipping

Clipping shapes

In the following example, we will be clipping two shapes. A rectangle and a circle.
ClippingShapes.java
package com.zetcode;

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();
}
}
In our example, we have a bouncing circle and a rotating rectangle. When these shapes overlap, the resulting area is filled with color.
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);
The rectangle is being rotated. It is always positioned in the middle of the panel.
GeneralPath path = new GeneralPath();
path.append(tx.createTransformedShape(rect1), false);
Here we get the shape of the rotated rectangle.
g2d.clip(circle);
g2d.clip(path);

g2d.fill(circle)
Here we restrict drawing to these two shapes. If they overlap, the interior of the resulting shape is filled with color.
g2d.setClip(new Rectangle(0, 0, w, h));
We reset the clip areas, before we draw the shapes.
Clipping Shapes
Figure: Clipping Shapes
In this part of the Java 2D tutorial, we have talked about clipping.

0 comments:

Post a Comment