Cómo 'obtener' un punto específico de un objeto de forma derivado de AffineTransform

Como un proyecto propio, estoy tratando de hacer el juego 'Asteroides'.

Actualmente, estoy atascado en tratar de descubrir cómo hacerlo para que los láseres disparados desde mi nave aparezcan desde elpropina de El Barco. Hasta ahora, he intentado experimentar con el uso deShape objetos.getBounds2D().getX() métodos, pero porquegetBounds2D() dibuja un rectángulo alrededor del polígono, los láseres terminan apareciendo desde la esquina de la 'caja' imaginaria alrededor de mi Polígonoship.

Aquí hay un gif de lo que tengo hasta ahora.

¿Hay alguna manera de "obtener" un punto específico de un objeto Shape; donde, en este caso, ese punto específico es la punta del barco.

Clase principal:

public class AsteroidGame implements ActionListener, KeyListener{

    public static AsteroidGame game;
    public Renderer renderer;

    public boolean keyDown = false;
    public int playerAngle = 0;

    public boolean left = false;
    public boolean right = false;
    public boolean go = false;
    public boolean back = false;
    public boolean still = true;
    public double angle = 0;
    public int turnRight = 5;
    public int turnLeft = -5;

    public Shape transformed;

    public ArrayList<Laser> lasers;
    public ArrayList<Shape> transformedLasers;

    public final int WIDTH = 1400;
    public final int HEIGHT = 800;

    public Ship ship;
    public Rectangle shipHead;
    public Shape shipHeadTrans;
    public Point headPoint;


    public AffineTransform transform = new AffineTransform();
    public AffineTransform lasTransform = new AffineTransform();
    public AffineTransform headTransform = new AffineTransform();

    public AsteroidGame(){
        JFrame jframe = new JFrame();
        Timer timer = new Timer(20, this);
        renderer = new Renderer();

        jframe.add(renderer);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setSize(WIDTH, HEIGHT);
        jframe.setVisible(true);
        jframe.addKeyListener(this);
        jframe.setResizable(false);

        int xPoints[] = {800, 780, 800, 820};
        int yPoints[] = {400, 460, 440, 460}; 

        //(800, 400) is the initial location of the 'tip' of the ship'.
        headPoint = new Point(800, 400);

        lasers = new ArrayList<Laser>();
        transformedLasers = new ArrayList<Shape>();

        ship = new Ship(xPoints, yPoints, 4, 0);
        transformed = transform.createTransformedShape(ship);

        shipHead = new Rectangle(headPoint);
        shipHeadTrans = transform.createTransformedShape(shipHead);
        //shipHeadTrans.getBounds2D().

        timer.start();

    }

    public void repaint(Graphics g){

        g.setColor(Color.BLACK);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        Graphics2D g2d = (Graphics2D)g;

        //drawing the ship
        g2d.setColor(Color.WHITE);
        g2d.draw(transformed);

        //drawing lasers
        g2d.setColor(Color.RED);
        for (int i = 0; i < transformedLasers.size(); i++){
            System.out.println(i);
            g2d.draw(transformedLasers.get(i));
        }



    }



    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

        /*The for if and else if statements are just to send the ship
         * to the other side of the canvas if it ever leaves the screen
         */
        if (transformed.getBounds2D().getMinX() > WIDTH){
            double tempAng = ship.getAng();
            double diff = 90-tempAng;

            transform.rotate(Math.toRadians(diff), ship.getCenterX(), ship.getCenterY());
            transform.translate(0,WIDTH);
            transform.rotate(Math.toRadians(-diff), ship.getCenterX(), ship.getCenterY());

        }

        else if (transformed.getBounds2D().getX() < 0){
            double tempAng = ship.getAng();
            double diff = 90-tempAng;
            transform.rotate(Math.toRadians(diff), ship.getCenterX(), ship.getCenterY());
            transform.translate(0,-WIDTH);
            transform.rotate(Math.toRadians(-diff), ship.getCenterX(), ship.getCenterY());
        }

        else if (transformed.getBounds2D().getY() > HEIGHT){
            double tempAng = ship.getAng();
            double diff = 180-tempAng;
            transform.rotate(Math.toRadians(diff), ship.getCenterX(), ship.getCenterY());
            transform.translate(0,HEIGHT);
            transform.rotate(Math.toRadians(-diff), ship.getCenterX(), ship.getCenterY());
        }

        else if (transformed.getBounds2D().getY() < 0){
            double tempAng = ship.getAng();
            double diff = 180-tempAng;
            transform.rotate(Math.toRadians(diff), ship.getCenterX(), ship.getCenterY());
            transform.translate(0,-HEIGHT);
            transform.rotate(Math.toRadians(-diff), ship.getCenterX(), ship.getCenterY());
        }


        if (right){
            ship.right();
            //rotating the ship
            transform.rotate(Math.toRadians(turnRight), ship.getCenterX(), ship.getCenterY());
            //rotating the 'tip' of the ship.
            headTransform.rotate(Math.toRadians(turnRight), ship.getCenterX(), ship.getCenterY());
        }

        else if (left){
            ship.left(); 
            //rotating the ship
            transform.rotate(Math.toRadians(turnLeft), ship.getCenterX(), ship.getCenterY());
            //rotating the 'tip' of the ship
            headTransform.rotate(Math.toRadians(turnLeft), ship.getCenterX(), ship.getCenterY());
        }
        if (go){
            ship.go();
        }
        else if (back){
            ship.reverse();
        }

        //moving and shaping each individual laser that had been shot
        for (int i = 0; i < transformedLasers.size(); i++){
            lasers.get(i).move();

            lasTransform = new AffineTransform();
            lasTransform.rotate(Math.toRadians(lasers.get(i).getAng()), transformed.getBounds2D().getX(), transformed.getBounds2D().getY());
            transformedLasers.set(i, lasTransform.createTransformedShape(lasers.get(i)));

        }

        //moving the ship
        ship.move();

        //moving the 'tip'
        shipHead.y -= ship.getSpeed();

        transformed = transform.createTransformedShape(ship);
        shipHeadTrans = headTransform.createTransformedShape(shipHead);


        renderer.repaint();

    }

    //defining a new laser
    public void fireLaser(){
        Laser tempLaser = new Laser((int)transformed.getBounds2D().getX(), (int)transformed.getBounds2D().getY(), 5, 10, ship.getAng());
        lasers.add(tempLaser);

        lasTransform = new AffineTransform();
        lasTransform.rotate(Math.toRadians(ship.getAng()), transformed.getBounds2D().getX(), transformed.getBounds2D().getY());
        transformedLasers.add(lasTransform.createTransformedShape(tempLaser));

    }

    public static void main(String[] args){
        game = new AsteroidGame();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        if (e.getKeyCode() == KeyEvent.VK_RIGHT){
            right = true;
            keyDown = true;
        }else if (e.getKeyCode() == KeyEvent.VK_LEFT){
            left = true;
            keyDown = true;
        }

        else if (e.getKeyCode() == KeyEvent.VK_UP){
            go = true;
        }
        else if (e.getKeyCode() == KeyEvent.VK_DOWN){
            back = true;
        }

        //fire laser
        if (e.getKeyCode() == KeyEvent.VK_SPACE){
            fireLaser();
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        if (e.getKeyCode() == KeyEvent.VK_RIGHT){
            right = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT){
            left = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_UP){
            go = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN){
            back = false;
        }
        still = true;
        keyDown = false;
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

Ship Class (aunque no creo que sea relevante)

package asteroidGame;

import java.awt.Polygon;
import java.util.Arrays;

public class Ship extends Polygon{

    /**
     * 
     */
    private double currSpeed = 0;

    private static final long serialVersionUID = 1L;
    public double angle;
    public int[] midX;
    public int[] midY;

    public Ship(int[] x, int[] y, int points, double angle){
        super(x, y, points);
        midX = x;
        midY = y;

        this.angle= angle;
    }


    public void right(){
        angle += 5;
    }
    public void left(){
        angle -= 5;
    }

    public void move(){
        for (int i = 0; i < super.ypoints.length; i++){
            super.ypoints[i] -= currSpeed;
            //System.out.println(super.ypoints[i]);
            //System.out.println(super.xpoints[i]);
        }
        //System.out.println(Arrays.toString(super.ypoints));



    }
    public double getSpeed(){
        return currSpeed;
    }


    public void reverse(){
        if (currSpeed  > -15) currSpeed -= 0.2;
    }

    public void go(){
        if (currSpeed < 25) currSpeed += 0.5;

    }

    public int getCenterX(){
        return super.xpoints[2];
    }
    public int getCenterY(){
        return super.ypoints[2];
    }

    public double getAng(){
        return angle;
    }
    public void test(){
        for (int x = 0; x < super.ypoints.length; x++){
            super.ypoints[x] += 1000;
        }
    }

    /*
    public void decrement(){
        if(currSpeed == 0){}

        else if (currSpeed > 0 && currSpeed < 15){
            currSpeed -= 0.05;

        }
        else if (currSpeed < 0 && currSpeed > -15){
            currSpeed += 0.05;

        }
        System.out.println("losing speed");
    }
    */
}

Clase láser (no creo que esto sea relevante tampoco, pero aquí tienes).

package asteroidGame;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;

public class Laser extends Rectangle{

    private double angle;

    public Laser(int x, int y , int width, int height, double ang){
        super(x, y, width, height);
        angle = ang;
        Rectangle tst = new Rectangle(); 


    }

    public void move(){
        super.y -= 35;
    }

    public double getAng(){
        return angle;
    }

    public boolean intersects (Rectangle2D r){
        //if intersects
        if (super.intersects(r)){
            return true;
        }
        else{
            return false;
        }

    }


}

Estaba pensando en girar el objeto Shapetransformed volver a un Polígono para obtener el punto, pero no estoy seguro de cómo o si eso funcionaría.

Respuestas a la pregunta(1)

Su respuesta a la pregunta