Reputation: 11
Using antialiasing in filling adjacent polygons in Java Swing can result in a fine gap between the polygons. The gap can be closed when using drawPolygon in addition to fillPolygon, but the polygon is drawn/filled twice and takes more than twice the time to just fill it.
Is there a way to get rid of the gap with just fillPolygon?
Here is some code to illustrate the behaviour:
import javax.swing.*;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
public class PolygonGap {
public static void main(String[] args) {
BufferedImage img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
Polygon p1 = new Polygon();
p1.addPoint(66, 210); p1.addPoint(70, 128); p1.addPoint(160, 152); p1.addPoint(159, 233);
Polygon p2 = new Polygon();
p2.addPoint(159, 233); p2.addPoint(160, 152); p2.addPoint(246, 175); p2.addPoint(247, 255);
Polygon p3 = new Polygon();
p3.addPoint(70, 128); p3.addPoint(74, 52); p3.addPoint(161, 76); p3.addPoint(160, 152);
Polygon p4 = new Polygon();
p4.addPoint(160, 152); p4.addPoint(161, 76); p4.addPoint(245, 99); p4.addPoint(246, 175);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
// g2.setColor(Color.black);
// g2.drawPolygon(p1); g2.drawPolygon(p2); g2.drawPolygon(p3); g2.drawPolygon(p4);
g2.setColor(Color.black);
g2.fillPolygon(p1); g2.fillPolygon(p2); g2.fillPolygon(p3); g2.fillPolygon(p4);
g2.dispose();
ImageIcon icon = new ImageIcon(img);
JLabel label = new JLabel(icon);
JOptionPane.showMessageDialog(null, label);
}
}
Uncomment the drawPolygon lines to see the gap vanish.
This code is only for demo purposes. In the original code all polygons may have a different color from each other.
Here the view with the gap:
A possible solution would be to add one pixel to the right and lower coordinate, so that they would overlap by one pixel. While working, it feels a bit dirty and comes with other consequences as it is part of a larger project where complex surfaces are computed and adding one pixel to the right and the bottom is mathematically more complex.
I also tried to translate(0.5, 0.5) (mentioned elsewhere on SO), but it didn't help.
Upvotes: 1
Views: 58
Reputation: 324157
but the polygon is drawn/filled twice and takes more than twice the time to just fill it.
Not sure why painting would be double.
Maybe you can use an Area
for the painting:
import javax.swing.*;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.geom.*;
public class PolygonGap2 {
public static void main(String[] args) {
BufferedImage img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
Polygon p1 = new Polygon();
p1.addPoint(66, 210); p1.addPoint(70, 128); p1.addPoint(160, 152); p1.addPoint(159, 233);
Polygon p2 = new Polygon();
p2.addPoint(159, 233); p2.addPoint(160, 152); p2.addPoint(246, 175); p2.addPoint(247, 255);
Polygon p3 = new Polygon();
p3.addPoint(70, 128); p3.addPoint(74, 52); p3.addPoint(161, 76); p3.addPoint(160, 152);
Polygon p4 = new Polygon();
p4.addPoint(160, 152); p4.addPoint(161, 76); p4.addPoint(245, 99); p4.addPoint(246, 175);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Area area = new Area();
area.add(new Area(p1));
area.add(new Area(p2));
area.add(new Area(p3));
area.add(new Area(p4));
g2.setColor(Color.BLACK);
g2.fill(area);
g2.dispose();
ImageIcon icon = new ImageIcon(img);
JLabel label = new JLabel(icon);
JOptionPane.showMessageDialog(null, label);
}
}
I can't measure the speed, so I don't know if it is any faster.
Upvotes: 1