【问题标题】:Finding AffineTransform origin on screen在屏幕上查找 AffineTransform 原点
【发布时间】:2015-04-10 01:54:27
【问题描述】:

假设我有一个 AffineTransform (transform) 并调用了它的一堆方法。可以说我旋转并翻译它。然后我用它转换一个图形对象(g2d):

g2d.transform(transform);

我想在 我的屏幕 上找到我的新 (0, 0) 所在的坐标。因此,如果我在这些坐标处用未转换的g2d 绘制一个矩形,而用我的转换后的g2d 绘制一个矩形,它们将重叠。那么我如何才能得到这一点,我是否需要做一些数学运算,AffineTransform 或 Graphics2D 是否有内置方式(我找不到)?

【问题讨论】:

    标签: java graphics affinetransform


    【解决方案1】:

    你可以...

    创建原始 Graphics 上下文 (Graphics#create) 的副本(这始终是一个好主意)然后将转换应用于副本(这将使原始不受影响,只是不要忘记 dispose完成后的副本)

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private BufferedImage img;
    
            public TestPane() {
                try {
                    img = ImageIO.read(your source image here...);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
    
            @Override
            public Dimension getPreferredSize() {
                return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - img.getWidth()) / 2;
                int y = (getHeight() - img.getHeight()) / 2;
                AffineTransform at = AffineTransform.getTranslateInstance(x, y);
                at.rotate(Math.toRadians(180), img.getWidth() / 2, img.getHeight() / 2);
                g2d.setTransform(at);
                g2d.drawImage(img, 0, 0, this);
                g2d.dispose();
    
                // I don't like touching the original ;)
                g2d = (Graphics2D) g.create();
                FontMetrics fm = g2d.getFontMetrics();
                g2d.drawString("Top Left", 0, 0 + fm.getAscent());
    
                String txt = "Bottom right";
                g2d.drawString(txt, getWidth() - fm.stringWidth(txt) - 1, ((getHeight() - fm.getHeight()) - 1) + fm.getAscent());
                g2d.dispose();
            }
    
        }
    
    }
    

    你可以...

    反转转换,如果它是一个复杂的转换总是很棘手......

    你可以...

    首先获取对原始转换的引用,应用新转换,绘制您需要绘制的任何内容,然后重新应用原始转换

    你可以...

    使用AffineTransform#setToIdentity 将转换“重置”回其原始状态...

        AffineTransform at = g2d.getTransform();
        at.translate(x, y);
        at.rotate(Math.toRadians(180), img.getWidth() / 2, img.getHeight() / 2);
        // Some drawing...
    
        at.setToIdentity();
        g2d.setTransform(at);
        // Back to basics
    

    【讨论】:

    • 这样做很糟糕,因为这是一个非常好的答案,但我确实需要一种方法来计算这一点。我的矩形示例只是显示了我想要的点。我希望我没有错过您的回答。
    • 我可能误解了这个问题,但本质上,您需要知道组件原点/位置 (0x0) 和 AffineTransform 之间的区别,否则您将无法计算点屏幕
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 2013-08-08
    • 1970-01-01
    • 2011-05-31
    • 2010-09-25
    • 1970-01-01
    相关资源
    最近更新 更多