Java Graphics2D翻译和缩放 [英] Java Graphics2D Translate and Scale

查看:207
本文介绍了Java Graphics2D翻译和缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有问题.我希望能够使用鼠标滚轮放大我的Graphics2D屏幕,但是我也希望能够翻译Graphics2D以便它恰好在我缩放的位置.到目前为止,这是正在发生的事情:" http://cdn.makeagif.com/media/6-11-2015/E0kYGY.gif ",它已正确转换为播放器的位置,但我希望它可以通过滚动鼠标滚轮来放大和缩小.到目前为止,这是我要执行的代码:

I have a problem. I want to be able to zoom into my Graphics2D screen using the mouse wheel but I want to be able to translate the Graphics2D as well so that it's right on the spot that I scaled. Here's what's happening so far: "http://cdn.makeagif.com/media/6-11-2015/E0kYGY.gif" It's translating to the player's position correctly but I want it to be zoomable in and out with the scrolling of the mouse wheel. Here's the code I have so far to do it:

private AffineTransform getCamTransform()
{
    AffineTransform t = new AffineTransform();
    float a = 400 - player.getX();
    float b = 250 - player.getY();
    t.translate(a, b);
    /*
     * Here's where I want to scale using the zoom
     * variable and also translate the g2d according
     * to the zoom variable.
     */
    return t;
}

private double zoom = 2.0D;

@Override
public void mouseWheelMoved(MouseWheelEvent e)
{
    zoom += e.getPreciseWheelRotation();
}

这只是我所拥有代码的一小部分.我有一种方法可以将所有内容绘制到屏幕上,但这只是返回必须应用于相机的变换.然后将转换设置为Graphics2D的先前转换.

This is just a small segment of the code I have. I have a method that draws everything to the screen but this is just to return the transform that must be applied to the camera. The transform is then set to the previous transform of the Graphics2D.

让我知道是否有更简单的方法可以做到这一点,或者我做错了所有事情.我也确实想提高CPU的效率.多亏有谁回答!

Let me know if there's an easier way to do this or I'm doing it all wrong. I do also want to be efficient on the CPU as well. Thanks to whoever answers!

推荐答案

基本概念是,您希望使它看起来好像图形仍在可见区域内居中.我首先想到要尝试扩展翻译点,也许这可能有用,但我无法使其正常工作(3岁的小孩子想读书不会给我太多时间进行实验).

The basic idea is, you want to make it appear as if the graphics is remaining centred within the viewable area. I first thought about trying to scale the translation points, and maybe that might work, but I couldn'y get it to work (3 year old wanting to read books didn't give me much time to experiment).

基本上,您需要添加另一个平移,其中根据可见区域和缩放比例将x/y点移动适当的量,以使图像在可见区域内看起来保持静止,然后应用缩放和正常平移在它上面...

Basically, you need to add another translation in which moves the x/y point the appropriate amount based on the viewable area and the zoom so the image appears to remain stationary within the viewable area, then apply the zoom and the normal translation on-top of it...

        double width = getWidth();
        double height = getHeight();

        double zoomWidth = width * zoom;
        double zoomHeight = height * zoom;

        double anchorx = (width - zoomWidth) / 2;
        double anchory = (height - zoomHeight) / 2;

        AffineTransform at = new AffineTransform();
        at.translate(anchorx, anchory);
        at.scale(zoom, zoom);
        at.translate(-100, -100);

因此,anchorx/y表示根据可见区域的宽度和高度需要偏移图形数量的结果,以便图像在其中保持居中"状态.

So, the anchorx/y represent the amount the resulting graphics would need be offset by, based on the viewable areas width and height, so that the image will remain "centred" within in it...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
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 double zoom = 1d;
        private BufferedImage img;

        public TestPane() {
            try {
                img = ImageIO.read(new File("..."));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            addMouseWheelListener(new MouseAdapter() {
                @Override
                public void mouseWheelMoved(MouseWheelEvent e) {
                    if (e.getPreciseWheelRotation() < 0) {
                        zoom -= 0.1;
                    } else {
                        zoom += 0.1;
                    }
//                  zoom += e.getPreciseWheelRotation();
                    if (zoom < 0.01) {
                        zoom = 0.01;
                    }

                    repaint();

                }
            });
        }

        public String format(double value) {
            return NumberFormat.getNumberInstance().format(value);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            double width = getWidth();
            double height = getHeight();

            double zoomWidth = width * zoom;
            double zoomHeight = height * zoom;

            double anchorx = (width - zoomWidth) / 2;
            double anchory = (height - zoomHeight) / 2;

            AffineTransform at = new AffineTransform();
            at.translate(anchorx, anchory);
            at.scale(zoom, zoom);
            at.translate(-100, -100);

            g2d.setTransform(at);
            g2d.drawImage(img, 0, 0, this);

            g2d.dispose();
        }

    }

}

可能有一个非常棒的数学公式可供您使用,但是我很愚蠢;)

There's probably a really awesome mathematical formula which you could use instead, but me be dumb ;)

这篇关于Java Graphics2D翻译和缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆