Java - Does subpixel line accuracy require an AffineTransform?

后端 未结 1 409
你的背包
你的背包 2021-02-08 17:44

I\'ve never worked with Java drawing methods before, so I decided to dive in and create an analog clock as a PoC. In addition to the hands, I draw a clock face that includes ti

1条回答
  •  遥遥无期
    2021-02-08 18:35

    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:

    screenshot

    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);
    }
    

    0 讨论(0)
提交回复
热议问题