Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Graphics2D line and shape drawing issues (rendered in wrong place)

I've drawn three arrows using Graphics2D.

  1. three drawLines
  2. draw(Shape)
  3. fill(Shape)

Here's what it looks like enlarged:

drawn arrows

I cannot understand two things:

  1. Why is the filled one smaller and shifted?
  2. Secondly, why do arrows 1. and 3. look different? Both consist of 3 antialiased lines. Shouldn't they (potentially) differ only in vertices?

Here's the whole code:

import javax.swing.*;
import java.awt.*;

public class ShapeTest extends JPanel
{
    public static void main(String [] args)
    {
        JFrame frame = new JFrame();
        frame.setSize(new Dimension(220, 200));
        frame.add(new ShapeTest());
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    @Override
    protected void paintComponent(Graphics graphics)
    {
        super.paintComponent(graphics);

        Graphics2D graphics2D = (Graphics2D)graphics;

        graphics.setColor(Color.white);
        graphics.fillRect(0, 0, this.getWidth(), this.getHeight());

        graphics2D.setColor(Color.black);
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics2D.drawLine(100, 40, 103, 46);
        graphics2D.drawLine(103, 46, 106, 40);
        graphics2D.drawLine(100, 40, 106, 40);

        graphics2D.fill(new Polygon(
                new int[]{100, 103, 106},
                new int[]{50, 56, 50},
                3
        ));

        graphics2D.draw(new Polygon(
                new int[]{100, 103, 106},
                new int[]{60, 66, 60},
                3
        ));
    }
}
like image 353
PKua Avatar asked Sep 18 '25 06:09

PKua


1 Answers

It seems I have found the answers to my question. I post them for other poeple who may face the same problem.

Smaller, because, as MadProgrammer said in a comment below the question, stokes are drawn along the edges through the middle, so a 1px stroke edges will be 0.5px to the each side of the shape edges.

Shifted because of rounding. When you draw a line with a float-precision coordinates it can be normalized in some way on some platforms. On Windows, at least for Path2D.Float and Line2D.Float, it rounds coords to integer numbers. I guess that the same goes for fill(Shape). Fotrunatelly, you can disable stroke normalization by:

g2D.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

It solves the problem:

arrows

Different, because of different rendering algorithms.

like image 181
PKua Avatar answered Sep 19 '25 19:09

PKua