problema de rotación de forma personalizada

Estoy tratando de rotar una forma personalizada alrededor de su centro, pero no puedo obtener el resultado como se esperaba.

lo que quiero es

*La forma debe girarse alrededor de su centro sin moverse.*

Lo que mi solución está haciendo actualmente esGirando una forma entera alrededor de su centro, por cada rotación cambia su posición.

Tengo varias formas, así que he creado una clase para encapsular una forma con su transformación en la siguiente clase

public abstract class Shoe implements Shape, ShoeShape {

    // variable declaration

    /**
     * 
     */
    public Shoe() {
        position = new Point();
        lastPosition = new Point();
    }




    public void draw(Graphics2D g2, AffineTransform transform, boolean firstTime) {

        AffineTransform af = firstTime ? getInitTransform()
                : getCompositeTransform();

        if (af != null) {


                Shape s = af.createTransformedShape(this);

                if (getFillColor() != null) {
                    g2.setColor(getFillColor());
                    g2.fill(s);
                } else {
                    g2.draw(s);
                }
            }

        }



    }




    public AffineTransform getCompositeTransform() {
            AffineTransform af = new AffineTransform();
        af.setToIdentity();
        af.translate(position.getX(), position.getY());
        Point2D centerP = calculateShapeCenter();
        af.rotate(orientation, centerP.getX(), centerP.getY());
        return af;
    }







    public void onMouseDrag(MouseEvent me, Rectangle2D canvasBoundary,
            int selectionOperation) {

        // shape operation can be either resize , rotate , translate ,
        switch (selectionOperation) {
        case MmgShoeViewer.SHAPE_OPERATION_MOVE:
            // MOVEMENT
            break;
        case MmgShoeViewer.SHAPE_OPERATION_ROTATE:

            Point2D origin = calculateShapeCenter();
            Point2D.Double starting = new Point2D.Double(me.getX(), me.getY());
            currentAngle = RotationHelper.getAngle(origin, starting);
            rotationAngle = currentAngle - startingAngle;
            rotate(rotationAngle);
            break;
        case MmgShoeViewer.SHAPE_OPERATION_RESIZE:
            break;
        default:
            System.out.println(" invalid select operation");
        }
    }



    public void onMousePress(MouseEvent me, Rectangle2D canvasBoundary,
            int selectionOperation) {

        // shape operation can be either resize , rotate , translate ,
        switch (selectionOperation) {
        case MmgShoeViewer.SHAPE_OPERATION_MOVE:
            break;
        case MmgShoeViewer.SHAPE_OPERATION_ROTATE:
            Point2D origin =  calculateShapeCenter();
            Point2D.Double starting = new Point2D.Double(me.getX(), me.getY());
            startingAngle = RotationHelper.getAngle(origin, starting);
            setShapeOperation(selectionOperation);
            break;
        case MmgShoeViewer.SHAPE_OPERATION_RESIZE:
            break;
        default:
            System.out.println(" invalid select operation");
        }
    }

    public void onMouseRelease(MouseEvent me, Rectangle2D canvasBoundary,
            int selectionOperation) {

        // shape operation can be either resize , rotate , translate ,
        switch (selectionOperation) {
        case MmgShoeViewer.SHAPE_OPERATION_MOVE:
            break;
        case MmgShoeViewer.SHAPE_OPERATION_ROTATE:
            // FIXME rotation angle computation
            setShapeOperation(-1);
            break;
        case MmgShoeViewer.SHAPE_OPERATION_RESIZE:
            break;
        default:
            System.out.println(" invalid select operation");
        }
    }

    public void rotate(double angle) {
        orientation = (float) angle;
    }


    public void translate(double deltaX, double deltaY) {

        position.setLocation(deltaX, deltaY);
        lastPosition.setLocation(deltaX, deltaY);
    }







    // another getter and setter

Estoy calculando el ángulo de rotación usando el siguiente método

public static double getAngle(Point2D origin, Point2D other) {

        double dy = other.getY() - origin.getY();
        double dx = other.getX() - origin.getX();
        double angle;

        if (dx == 0) {// special case
            angle = dy >= 0 ? Math.PI / 2 : -Math.PI / 2;
        } else {
            angle = Math.atan(dy / dx);
            if (dx < 0) // hemisphere correction
                angle += Math.PI;
        }
        // all between 0 and 2PI
        if (angle < 0) // between -PI/2 and 0
            angle += 2 * Math.PI;
        return angle;
    }

en prensa de ratón evento de la escucha del lienzo del ratón

selectedShape.onMousePress(me, canvasBoundary, shoeViewer
                .getShapeOperation());

Solo estoy llamando al método onMousePress de la forma seleccionada

y en mi método de arrastrar con el mouse del detector de lienzo del mouse, solo invoco el método onMouseDrag de la forma seleccionada que actualiza el ángulo de rotación como se puede ver desde la primera clase

selectedShape.onMouseDrag(me, canvasBoundary, shoeViewer
                .getShapeOperation());

y puede ver el método de dibujo de la forma individual, para dibujar la forma de acuerdo con la transformación actual, estoy llamando desde paintComponent como

Iterator<Shoe> shoeIter = shoeShapeMap.values().iterator();

        while (shoeIter.hasNext()) {

            Shoe shoe = shoeIter.next();
            shoe.draw(g2, firstTime);

        }

donde shoeShapeMap contiene todas las formas personalizadas actualmente en el lienzo.

¿Estoy cometiendo un error al calcular el ángulo o determinar el punto de anclaje? mi solución actual rota la forma 360 grados al verificar todas las condiciones [90 grados, etc.] como se puede ver en el método mencionado anteriormente.

¿Quiero que la forma se gire alrededor de su centro sin cambiar el tamaño de sus posiciones? En la palabra es difícil de explicar, así que, por favor, sugiérame una mejor manera de mostrar aquí lo que quiero lograr.

Creo que he mencionado todas las cosas relacionadas con este tema. Si tienes alguna duda no dudes en preguntarme.

Encontré 2 publicaciones relacionadas aquí pero no pude encontrar mucha información de ellos.

Respuestas a la pregunta(1)

Su respuesta a la pregunta