0

I am trying to rotate a custom shape around its center, but can not get the result as expected.

what i want is

*shape should be rotated around its center without moving itself.*

what my solution is currently doing is rotating a whole shape around its center , by every rotation its changing its position.

I have multiple shapes so i have created a class to encapsulate a shape with its transform in following class

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

I am calculating angle of rotation using following method

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

in mouse press event of the canvas mouse listener

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

i am just calling selected shape's onMousePress method

and in my mouse drag method of the canvas mouse listener , i am just calling the selected shape's onMouseDrag method which updates the rotation angle as you can see from the very first class

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

and you can see the draw method of the individual shape , to draw the shape according to current transform , i am calling from paintComponent like

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

        while (shoeIter.hasNext()) {

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

        }

where shoeShapeMap contains all of the custom shapes currently on the canvas.

is i am doing mistake in calculating angle or determining anchor point ? my current solution rotates shape 360 degree by checking all the conditions[90 degree etc.] as you can see in the above mentioned method.

i want the shape should be rotated around its center without resizing its positions ? in the word it is difficult to explain , so please suggest me any better way to show here what i want to accomplish ?

i think i have mentioned all the things related to this issue. if you have any doubts please feel free to ask me.

i found 2 related posts here but i could not find much information from them.

Mihir
  • 2,480
  • 7
  • 38
  • 57
  • For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Feb 12 '13 at 09:30
  • @Andrew i have edited the code and leaving only code which will help to figure out the issue. – Mihir Feb 12 '13 at 12:22
  • Post 1 SSCCE. Should include 1 main. – Andrew Thompson Feb 12 '13 at 12:24
  • @Andrew i think the only methods of interest for you might be the getCompositeTransform method , i think there is sub problem. – Mihir Feb 12 '13 at 12:26
  • try to translate after rotate, and maybe translate with -values – Dariusz Feb 12 '13 at 12:27
  • *"i think the only methods of interest for you"* I am interested in looking at an **SSCCE.** -1 for not taking the hint the first 2 times. – Andrew Thompson Feb 12 '13 at 12:27
  • @Dariusz Wawer i think you didn't take a look at my method getCompositeTransform i have already take rotate method with translation anchor point – Mihir Feb 12 '13 at 12:34
  • @Andrew i am really disappointed by your behaviour, i invited you 2 times to answer a solution ant i thought you r real geneious , but rather focusing on problem you r wasting my time. i don't want anser from you thanks for your time . – Mihir Feb 12 '13 at 12:36
  • @Andrew i found solution by my self. – Mihir Feb 12 '13 at 17:22
  • @DariuszWawer i will accept your comment as an answer if you post it as an answer. actually during testing i found the same and then i read your comments but it exactly did what i want.thanks – Mihir Feb 13 '13 at 14:56

1 Answers1

1

I think that the solution may be to (either/and):

  • invert the order of operations on your AffineTransform, put translate after rotate
  • use -x and -y for your translation values
Dariusz
  • 21,561
  • 9
  • 74
  • 114
  • actually the solution is in rotate method by mistake i take anchor point previous translation + center , it should be only center because translation already done or i need to inverse the transformation order rotate then translate. – Mihir Feb 13 '13 at 15:15