проблема с поворотом нестандартной формы

Я пытаюсь повернуть произвольную фигуру вокруг ее центра, но не могу получить ожидаемый результат.

то, что я хочу, это

* фигуру следует вращать вокруг своего центра, не перемещаясь. *

в настоящее время мое решение вращает всю фигуру вокруг ее центра, при каждом повороте она меняет свое положение.

У меня есть несколько фигур, поэтому я создал класс для инкапсуляции фигуры с ее преобразованием в следующем классе

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

Я рассчитываю угол поворота, используя следующий метод

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;
    }

в событии нажатия мыши для слушателя мыши холста

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

Я просто вызываю метод onMousePress выбранной формы

и в моем методе перетаскивания мышью слушателя мыши холста я просто вызываю метод onMouseDrag выбранной формы, который обновляет угол поворота, как вы можете видеть из самого первого класса

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

и вы можете увидеть метод рисования отдельной формы, чтобы нарисовать форму в соответствии с текущим преобразованием, я вызываю из paintComponent, например

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

        while (shoeIter.hasNext()) {

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

        }

где shoeShapeMap содержит все пользовательские формы, которые в данный момент находятся на холсте.

я делаю ошибку при вычислении угла или определении точки привязки? мое текущее решение поворачивает фигуру на 360 градусов, проверяя все условия [90 градусов и т. д.], как вы можете видеть в вышеупомянутом методе.

я хочу, чтобы фигура вращалась вокруг своего центра, не меняя ее положения? Словом, это сложно объяснить, поэтому, пожалуйста, предложите мне лучший способ показать здесь, чего я хочу достичь?

Думаю, я упомянул все, что связано с этой проблемой. если у вас есть какие-либо сомнения, не стесняйтесь спрашивать меня.

Я нашел здесь 2 связанных сообщения, но я не смог найти от них много информации.


person Mihir    schedule 12.02.2013    source источник
comment
Чтобы быстрее получить более качественную помощь, опубликуйте SSCCE.   -  person Andrew Thompson    schedule 12.02.2013
comment
@Andrew, я отредактировал код и оставил только код, который поможет разобраться в проблеме.   -  person Mihir    schedule 12.02.2013
comment
Опубликовать 1 SSCCE. Должен включать 1 main.   -  person Andrew Thompson    schedule 12.02.2013
comment
@Andrew, я думаю, что единственными интересными для вас методами может быть метод getCompositeTransform, я думаю, что есть дополнительная проблема.   -  person Mihir    schedule 12.02.2013
comment
попробуйте перевести после поворота и, возможно, перевести с -values   -  person Dariusz    schedule 12.02.2013
comment
Я думаю, что это единственные методы, которые могут вас заинтересовать. Мне интересно посмотреть на SSCCE. -1 за то, что я не понял намек первые 2 раза.   -  person Andrew Thompson    schedule 12.02.2013
comment
@Dariusz Wawer, я думаю, вы не взглянули на мой метод getCompositeTransform, я уже использовал метод поворота с точкой привязки перевода   -  person Mihir    schedule 12.02.2013
comment
@ Эндрю, я очень разочарован твоим поведением, я дважды приглашал тебя ответить на вопрос, и я думал, что ты очень гениальный, но сосредоточившись на проблеме, ты тратишь мое время зря. Я не хочу, чтобы ты ответил, спасибо за уделенное время.   -  person Mihir    schedule 12.02.2013
comment
@ Андрей, я нашел решение самостоятельно.   -  person Mihir    schedule 12.02.2013
comment
@DariuszWawer, я приму ваш комментарий как ответ, если вы опубликуете его как ответ. на самом деле во время тестирования я обнаружил то же самое, а затем я прочитал ваши комментарии, но он сделал именно то, что я хочу. спасибо   -  person Mihir    schedule 13.02.2013


Ответы (1)


Я думаю, что решение может заключаться в (либо / и):

  • инвертировать порядок операций в AffineTransform, поставить перевод после поворота
  • используйте -x и -y для значений перевода
person Dariusz    schedule 13.02.2013
comment
на самом деле решение находится в методе поворота по ошибке, я беру точку привязки предыдущий перевод + центр, он должен быть только центром, потому что перевод уже выполнен, или мне нужно инвертировать порядок преобразования, повернуть, а затем перевести. - person Mihir; 13.02.2013