Java - Does subpixel line accuracy require an AffineTransform?

久未见 提交于 2019-12-03 07:31:59

Line2D.double() methods cannot draw with subpixel accuracy.

Wrong, using RenderingHints.VALUE_STROKE_PURE the Graphics2D object can draw "subpixel" accuracy with the shape Line2D.


I assume I could use an AffineTransform with rotation only, as opposed to having to perform a supersampling. Is this the only/best method of drawing with sub-pixel accuracy? Or is there a potentially faster solution?

I think you are missing somthing here. The Graphics2D object already holds a AffineTransform and it is using it for all drawing actions and its cheap performance wise.


But to get back to you what is missing from your code - this is missing:

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

Below is a self contained example that produces this picture:

public static void main(String[] args) throws Exception {

    final JFrame frame = new JFrame("Test");

    frame.add(new JComponent() {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g;

            System.out.println(g2d.getTransform());
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                 RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
                                 RenderingHints.VALUE_STROKE_PURE);

            double dia = Math.min(getWidth(), getHeight()) - 2;

            for (int i = 0; i < 60 ; i++) {
                double angle = 2 * Math.PI * i / 60;
                g2d.draw(new Line2D.Double(
                        (dia / 2) + Math.cos(angle) * dia / 2.1d,
                        (dia / 2) + Math.sin(angle) * dia / 2.1d,
                        (dia / 2) + Math.cos(angle) * dia / 2.05d,
                        (dia / 2) + Math.sin(angle) * dia / 2.05d));
            }

            g2d.draw(new Ellipse2D.Double(1, 1, dia - 1, dia - 1));
        }
    });

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 400);
    frame.setVisible(true);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!