我上课了Airplane。在这个类中,我有img一个BufferedImage类型的变量。更重要的是,我有WorldMap重写功能的类paintComponent(Graphics g):
Airplane
img
BufferedImage
paintComponent(Graphics g)
@Override public void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; g2d.drawImage(mapa, 0, 0, getWidth(), getHeight(), null); drawAirplanes(g2d); }
函数drawAirplanes()看起来像这样:
drawAirplanes()
private void drawAirplane(Graphics2D g){ for(Samolot i: s){ i.rotateAirplane(); g.drawImage(i.getImg(),i.getX(),i.getY(),(int)i.getDim().getWidth(),(int)i.getDim().getHeight(), null); } }
它只需要1)旋转飞机(飞机对象内部的BufferedImage)2)画他。
我的Airplane.rotateAirplane()函数如下所示:
public void rotateSamolot() { AffineTransform tx = new AffineTransform(); tx.translate(10,10); //10, 10 is height and width of img divide by 2 tx.rotate(Math.PI / 2); tx.translate(-10,-10); AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR); BufferedImage newImage =new BufferedImage(20, 20, img.getType()); //20, 20 is a height and width of img ofc op.filter(img, newImage); this.img = newImage; }
我运行我的程序时,ofc仅mapa绘制对象。当我删除此车道时
mapa
this.img = newImage;
我也有我的飞机,但是没有旋转。
主要的问题(我可以看到)是Graphics上下文的转换,它与旋转将发生的位置相抵消。
Graphics
默认情况下,我“认为”旋转发生在Graphics上下文的左上角(0x0位置,你已将其转换为其他位置),这可能导致图像旋转出帧(或可见区域) )
你应该提供旋转发生的“锚点”,通常,中心是我的个人喜好。
以下示例仅具有一个主图像(由于尺寸限制,我不得不对其进行缩放,但你可能不需要此图像)。然后,我用它生成一个“旋转的”实例,该实例的大小允许图像适合放入其中。trig带来了很多乐趣-我从某个地方偷了代码,因此归功于该开发人员。
该示例允许你单击任意位置,它将更改旋转轴,因此你可以看到发生了什么。默认位置是窗格的中心…
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class SampleRotation { public static void main(String[] args) { new SampleRotation(); } public SampleRotation() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } final RotationPane rotationPane = new RotationPane(); final JSlider slider = new JSlider(0, 100); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { double angle = 720d * (slider.getValue() / 100d); rotationPane.setAngle(angle); } }); slider.setValue(0); JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(rotationPane); frame.add(slider, BorderLayout.SOUTH); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class RotationPane extends JPanel { private BufferedImage img; private BufferedImage rotated; private double angle; private Point clickPoint; public RotationPane() { try { img = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/issue459.jpg")); BufferedImage scaled = new BufferedImage(img.getWidth() / 2, img.getHeight() / 2, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = scaled.createGraphics(); g2d.setTransform(AffineTransform.getScaleInstance(0.5d, 0.5d)); g2d.drawImage(img, 0, 0, this); g2d.dispose(); img = scaled; setAngle(0d); } catch (IOException ex) { ex.printStackTrace(); } addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { clickPoint = e.getPoint(); repaint(); } }); } public void setAngle(double angle) { this.angle = angle; double rads = Math.toRadians(getAngle()); double sin = Math.abs(Math.sin(rads)), cos = Math.abs(Math.cos(rads)); int w = img.getWidth(); int h = img.getHeight(); int newWidth = (int) Math.floor(w * cos + h * sin); int newHeight = (int) Math.floor(h * cos + w * sin); rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = rotated.createGraphics(); AffineTransform at = new AffineTransform(); at.translate((newWidth - w) / 2, (newHeight - h) / 2); int x = clickPoint == null ? w / 2 : clickPoint.x; int y = clickPoint == null ? h / 2 : clickPoint.y; at.rotate(rads, x, y); g2d.setTransform(at); g2d.drawImage(img, 0, 0, this); g2d.setColor(Color.RED); g2d.drawRect(0, 0, newWidth - 1, newHeight - 1); g2d.dispose(); repaint(); } public double getAngle() { return angle; } @Override public Dimension getPreferredSize() { return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(this), img.getHeight(this)); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (rotated != null) { Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - rotated.getWidth()) / 2; int y = (getHeight() - rotated.getHeight()) / 2; g2d.drawImage(rotated, x, y, this); g2d.setColor(Color.RED); x = clickPoint == null ? getWidth() / 2 : clickPoint.x; y = clickPoint == null ? getHeight()/ 2 : clickPoint.y; x -= 5; y -= 5; g2d.drawOval(x, y, 10, 10); g2d.dispose(); } } } }