Search code examples
javafxrotationcenterrectangles

JavaFX rotate rectangle about center?


I'm trying rotate a rectangle around its center. The rotation is being drawn to a canvas using the GraphicsContext ie gc. Here is my draw code.

gc.save();    
gc.translate(center.x, center.y);
gc.rotate(this.angle);
gc.strokeRect(0,0, this.width, this.height);   
gc.restore();

This moves the rectangle to its center but then it rotates the rectangle around its top left point. I tried subtracting half the length and width of the sides but that just made it fly all over the place. I suck at math maybe someone here who is better can show me what I'm doing wrong.

I also have stored all four points (corners) of the rectangle if that information is needed.

Thanks, Joe


Solution

  • A rotation around a specified point needs to be composed from translate transformations and rotations around the origin as follows:

    1. Use translation to move the center of the rotation to the origin.
    2. rotate around the origin
    3. use inverse translation to the first translation

    The third part is missing from your code.

    Example

    @Override
    public void start(Stage primaryStage) throws Exception {
        Canvas canvas = new Canvas(400, 400);
        double x = 50;
        double y = 100;
        double width = 100;
        double height = 200;
    
        GraphicsContext gc = canvas.getGraphicsContext2D();
        double rotationCenterX = (x + width) / 2;
        double rotationCenterY = (y + height) / 2;
    
        gc.save();
        gc.translate(rotationCenterX, rotationCenterY);
        gc.rotate(45);
        gc.translate(-rotationCenterX, -rotationCenterY);
    
        gc.fillRect(0, 0, width, height);
        gc.restore();
    
        Scene scene = new Scene(new Group(canvas));
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    

    You could also simply use a Rotate with a specified pivot to achieve the desired effect:

    @Override
    public void start(Stage primaryStage) throws Exception {
        Canvas canvas = new Canvas(400, 400);
        double x = 50;
        double y = 100;
        double width = 100;
        double height = 200;
    
        GraphicsContext gc = canvas.getGraphicsContext2D();
        double rotationCenterX = (x + width) / 2;
        double rotationCenterY = (y + height) / 2;
    
        gc.save();
        gc.transform(new Affine(new Rotate(45, rotationCenterX, rotationCenterY)));
        gc.fillRect(0, 0, width, height);
        gc.restore();
    
        Scene scene = new Scene(new Group(canvas));
        primaryStage.setScene(scene);
        primaryStage.show();
    }