BKN
BKN

Reputation: 11

Display adjacent Java Swing Polygons without gap even when using antialiasing

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

Answers (1)

camickr
camickr

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

Related Questions