Java Graphics2D 平移和缩放
Java Graphics2D Translate and Scale
我有问题。我希望能够使用鼠标滚轮放大我的 Graphics2D
屏幕,但我也希望能够平移 Graphics2D
以便它位于我缩放的位置。这是到目前为止发生的事情:“http://cdn.makeagif.com/media/6-11-2015/E0kYGY.gif”它正确地转换为玩家的位置,但我希望它可以随着鼠标滚轮的滚动而放大和缩小。这是我到目前为止要做的代码:
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();
}
这只是我拥有的一小部分代码。我有一种方法可以将所有内容绘制到屏幕上,但这只是 return 必须应用于相机的变换。然后将变换设置为 Graphics2D
.
的前一个变换
如果有更简单的方法或者我做错了,请告诉我。我也希望在 CPU 上也能有效率。感谢回答者!
基本思路是,您想让它看起来好像图形在可视区域内保持居中。我首先想到尝试缩放翻译点,也许这可能会起作用,但我无法让它起作用(3 岁想看书没有给我太多时间来试验)。
基本上,您需要添加另一个平移,根据可视区域和缩放将 x/y 点移动适当的量,使图像在可视区域内看起来保持静止,然后应用缩放以及其上的正常翻译...
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
表示根据可视区域的宽度和高度,生成的图形需要偏移的量,以便图像将保留在其中 "centred"。 .
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();
}
}
}
可能有一个非常棒的数学公式,您可以用它来代替,但我是笨蛋 ;)
我有问题。我希望能够使用鼠标滚轮放大我的 Graphics2D
屏幕,但我也希望能够平移 Graphics2D
以便它位于我缩放的位置。这是到目前为止发生的事情:“http://cdn.makeagif.com/media/6-11-2015/E0kYGY.gif”它正确地转换为玩家的位置,但我希望它可以随着鼠标滚轮的滚动而放大和缩小。这是我到目前为止要做的代码:
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();
}
这只是我拥有的一小部分代码。我有一种方法可以将所有内容绘制到屏幕上,但这只是 return 必须应用于相机的变换。然后将变换设置为 Graphics2D
.
如果有更简单的方法或者我做错了,请告诉我。我也希望在 CPU 上也能有效率。感谢回答者!
基本思路是,您想让它看起来好像图形在可视区域内保持居中。我首先想到尝试缩放翻译点,也许这可能会起作用,但我无法让它起作用(3 岁想看书没有给我太多时间来试验)。
基本上,您需要添加另一个平移,根据可视区域和缩放将 x/y 点移动适当的量,使图像在可视区域内看起来保持静止,然后应用缩放以及其上的正常翻译...
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
表示根据可视区域的宽度和高度,生成的图形需要偏移的量,以便图像将保留在其中 "centred"。 .
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();
}
}
}
可能有一个非常棒的数学公式,您可以用它来代替,但我是笨蛋 ;)