旋转图像旋转后如何获取某个点?

How can I get a certain point of a rotating image after it has been rotated?

我已经在自上而下的游戏上工作了大约一两天,我试图弄清楚如何在我平移和旋转并对象回到其原始位置后获得一个点。我有一个图像(武器),我根据鼠标位置和播放器旋转它,但是,我想在旋转图像后获得旋转图像的某个点,这样我就可以使用这个点来设置开始绘制位置用于子弹、动画等。有谁知道我该如何解决这个问题?谢谢!!

private Point hand, location, handle, barrelExit;
private BufferedImage image;

private double theta;

public WeaponSpriteBase(BufferedImage image, Point location, Point handle, Point barrelExit) {

    super(image, location);

    this.image = image;
    this.location = location;
    this.handle = handle;
    this.barrelExit = barrelExit;

    //Sets the hand location getter
    hand = PlayerSprite.playerHand();

}

public void draw(Graphics2D g2, int currentMouseX, int currentMouseY) {

    theta = PlayerSprite.DegreeFinder(currentMouseX, currentMouseY);

    //Refreshes the hands location getter
    hand = PlayerSprite.playerHand();

    setLocation(hand.x - handle.x, hand.y - handle.y);

    g2.translate(hand.x, hand.y);
    g2.rotate(-Math.toRadians(theta));

    setLocation(-handle.x, - handle.y);

    if(theta > 90 && theta < 270) {
        flipVert(g2);
    }

    else {
        super.draw(g2);
    }

    g2.rotate(Math.toRadians(theta));
    g2.translate(-hand.x, -hand.y);

    g2.setColor(Color.RED);
    g2.drawRect(hand.x - 1, hand.y - 1, 2, 2);
    g2.setColor(Color.black);


    //Want to get a certain point on the image and draw it here (with barrelExit.x , barrelExit.y) without rotating it

    
}

}

如果你知道...

  • 武器位置
  • 方向角度
  • 长度(从中心点到终点)

然后您可以简单地应用“圆上的点”方法来解决问题,例如...

蓝线是武器,红线是弹道的投影。奇怪的是,它正在计算射弹应该遵循的起点和终点

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;

public class Main {

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    enum WeaponInput {
        LEFT, RIGHT, NONE
    }

    public class TestPane extends JPanel {

        private static final double MIN_WEAPON_ANGLE = -85;
        private static final double MAX_WEAPON_ANGLE = 85;

        private double angleOfWeapon = 0;
        private double weaponAngleDelta = 1;

        private WeaponInput weaponInput = WeaponInput.NONE;

        private Timer timer;

        public TestPane() {
            setBackground(Color.BLACK);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "Pressed.weaponMoveLeft");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "Pressed.weaponMoveRight");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "Pressed.weaponReleasedLeft");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "Pressed.weaponReleasedRight");

            WeaponMovementAction.WeaponObserver weaponObserver = new WeaponMovementAction.WeaponObserver() {
                @Override
                public void weaponDidMove(WeaponInput weaponInput) {
                    TestPane.this.weaponInput = weaponInput;
                }
            };

            am.put("Pressed.weaponMoveLeft", new WeaponMovementAction(WeaponInput.LEFT, weaponObserver));
            am.put("Pressed.weaponMoveRight", new WeaponMovementAction(WeaponInput.RIGHT, weaponObserver));
            am.put("Pressed.weaponReleasedLeft", new WeaponMovementAction(WeaponInput.NONE, weaponObserver));
            am.put("Pressed.weaponReleasedRight", new WeaponMovementAction(WeaponInput.NONE, weaponObserver));

            timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    switch (weaponInput) {
                        case LEFT:
                            angleOfWeapon -= weaponAngleDelta;
                            break;
                        case RIGHT:
                            angleOfWeapon += weaponAngleDelta;
                            break;
                    }
                    if (angleOfWeapon < MIN_WEAPON_ANGLE) {
                        angleOfWeapon = MIN_WEAPON_ANGLE;
                    } else if (angleOfWeapon > MAX_WEAPON_ANGLE) {
                        angleOfWeapon = MAX_WEAPON_ANGLE;
                    }

                    repaint();
                }
            });
            timer.start();
        }

        protected Point2D getPointOnCircle(double degress, double radius) {
            double rads = Math.toRadians(degress - 90); // 0 becomes the top

            // Calculate the outter point of the line
            double xPosy = Math.cos(rads) * radius;
            double yPosy = Math.sin(rads) * radius;

            return new Point2D.Double(xPosy, yPosy);
        }

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

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

            int centerX = getWidth() / 2;
            int centerY = getHeight() / 2;

            g2d.setColor(Color.WHITE);
            g2d.drawRect(centerX - 20, centerY - 20, 40, 40);

            g2d.setColor(Color.RED);
            g2d.translate(centerX, centerY - 20);

            // Projection of projectile
            g2d.setColor(Color.BLUE);
            Point2D endOfWeaponPoint = getPointOnCircle(angleOfWeapon, 20);
            g2d.draw(new Line2D.Double(new Point2D.Double(0, 0), endOfWeaponPoint));

            // Weapon direction
            int radius = Math.max(getWidth(), getHeight());
            g2d.setColor(Color.RED);
            Point2D poc = getPointOnCircle(angleOfWeapon, radius);
            g2d.draw(new Line2D.Double(endOfWeaponPoint, poc));

            g2d.dispose();
        }

    }

    public class WeaponMovementAction extends AbstractAction {

        public interface WeaponObserver {

            public void weaponDidMove(WeaponInput weaponInput);
        }

        private WeaponInput weaponInput;
        private WeaponObserver observer;

        public WeaponMovementAction(WeaponInput weaponInput, WeaponObserver observer) {
            this.weaponInput = weaponInput;
            this.observer = observer;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            getObserver().weaponDidMove(getWeaponInput());
        }

        public WeaponInput getWeaponInput() {
            return weaponInput;
        }

        public WeaponObserver getObserver() {
            return observer;
        }

    }
}