Java 仿射变换在这段代码中是如何工作的?

Java 仿射变换在这段代码中是如何工作的?,java,Java,下面的代码工作正常,但我在理解某些细节时遇到了困难。有人能帮我理解仿射变换是如何旋转图像的吗 package pks; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; impor

下面的代码工作正常,但我在理解某些细节时遇到了困难。有人能帮我理解仿射变换是如何旋转图像的吗

package pks;

import java.awt.Dimension;
import java.awt.EventQueue;
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 javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class rotate {

    public static void main(String[] args) {
        new rotate();
    }

    public rotate() {
        EventQueue.invokeLater(new Runnable() {

           public void run() {

                final RotationPane rotationPane = new RotationPane(); // initilize object of RotationPane class
                JFrame frame = new JFrame("Test");

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(rotationPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class RotationPane extends JPanel {

        private BufferedImage img;
        private BufferedImage rotated;

        private double angle;

        public RotationPane() {

            try {
                img = ImageIO.read(new File("C:\\Users\\pardeep\\Desktop\\tomb1.jpg")); // path of the image to be rotated
                setAngle(45);
            } 
            catch (IOException ex) {
            }

        }

        public void setAngle(double angle) {
            this.angle = angle;

            // Using Affine transform we will calculate the new values
            //x=vcos (theta)+wsin(theta)
            //y=vcos(theta)+ wsin(theta)

            double rads = Math.toRadians(angle);  // calculating angle in radian
            double sin = Math.abs(Math.sin(rads)),  //calculating sin theta
                   cos = Math.abs(Math.cos(rads)); // calculating cos theta

            int w = img.getWidth();
            int h = img.getHeight();

            int newWidth = (int) Math.floor(w * cos + h * sin);  //using affine transform
            int newHeight = (int) Math.floor(h * cos + w * sin);

            rotated = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);

            Graphics2D g2d = rotated.createGraphics(); //rotating planes.....

            AffineTransform plane = new AffineTransform();

            plane.translate((newWidth - w) / 2, (newHeight - h) / 2);

            int x=w/2;
            int y=h/2;

            plane.rotate(Math.toRadians(45), x, y);

            g2d.setTransform(plane);
            g2d.drawImage(img, 0, 0, this);
        }


        public Dimension getPreferredSize() {
            return  new Dimension(800,   // setting the window size
                              800);
        }

        protected void paintComponent(Graphics g) {
            // super.paintComponent(g); no need for it

            if (rotated != null) {   // drawing image on 2 dimentional size surface
                Graphics2D g2d = (Graphics2D) g.create(); 

                int x = (getWidth() - rotated.getWidth()) / 2;
                int y = (getHeight() - rotated.getHeight()) / 2;

                g2d.drawImage(rotated, x, y, this); // overriding the method......
            }
        }        
    }    
}

你到底不明白什么<代码>平面。旋转(数学。托拉半径(45),x,y)围绕中心点顺时针旋转图像45度<代码>平面平移((新宽度-w)/2,(新高度-h)/2)与平面相同。平移(newWidth/2-w/2,newHeight/2-h/2)因此它计算新中心和旧中心之间的差异,并根据该差异移动整个图片

我应该提到仿射变换以相反的顺序应用变换。 所以如果你写这个

plane.translate((newWidth - w) / 2, (newHeight - h) / 2);
int x=w/2;
int y=h/2;
plane.rotate(Math.toRadians(45), x, y);

然后,图像的每个像素首先顺时针旋转45度,然后移动,而不是相反方向。这样做是因为变换应该应用于坐标系。将变换A和变换B应用于坐标系在数学上等同于将B和A应用于图像的像素。

你知道A是什么吗?paintComponent方法在JPanel的中心绘制图像。为此,它计算JPanel中心和图像中心之间的差值,以确定在何处绘制它。但它已经使用g2d.drawImage绘制了图片(img,0,0,this);这个方法…那么我们为什么使用这个方法g2d.drawImage(旋转,x,y,这个)//在设置角度方法中,图像被绘制到另一个图像中,而不是屏幕上。