Rotating Java 2D Graphics Around Specified Point

前端 未结 1 2067
北荒
北荒 2021-01-07 02:37

I\'m trying to write a program that will draw several shapes rotated around a center point. The result should be something like a Spirograph. I\'m trying to test it using

1条回答
  •  礼貌的吻别
    2021-01-07 02:51

    Remember, translate and rotate are compounding, that is, each time you apply them, they add to the current transformation.

    There are a number of ways you might be able to achieve this, but first, we need to make a copy of the Graphics context. It's kind of important any time you mess with the transform in particular, you do so with a copy of the Graphics context, as this will leave the original unaffected (and won't effect anything that might be painted after)

    Graphics2D g2d = (Graphics2D) g.create();
    //...
    g2d.dispose();
    

    So anything you do to g2d now, won't affect the state of g

    Now, we can use the "compounding" effect of a transform to our advantage

    Rectangle tangle = new Rectangle(0, 0, radius, radius);
    //g2d.translate(centerX, centerY);
    g2d.rotate(Math.toRadians(angle), centerX, centerY);
    g2d.draw(tangle);
    

    So, all this does is applies the value of angle to the copy of the Graphics context on each loop. The anchor point is set to the centerX and centerY points

    Okay, that looks okay, but what happens if I resize the window?

    Okay, not really what I was expecting. This occurs for a combination of reasons, the size of the shape, the anchor point, the rotation, the translation offset, these are all compounding to produce the effect (cool though).

    Okay, so, instead, we can simply create a new transform for each loop instead, supplying the exact parameters we want, for example...

    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setColor(Color.blue);
    
    Rectangle tangle = new Rectangle(0, 0, radius, radius);
    g2d.translate(centerX, centerY);
    g2d.rotate(Math.toRadians(curAngle));
    g2d.draw(tangle);
    curAngle += angle;
    g2d.dispose();
    

    This now produces...

    While playing around with the code, I noticed that as I increased the number of repeats, I wasn't getting the desired results.

    After same digging, I changed

    angle = 360 / repeats;
    

    to

    angle = 360.d / repeats;
    

    which stopped the integer division issue (and truncating of the decimal values) and started to produce the desired results

    A simple before and after comparison...

    0 讨论(0)
提交回复
热议问题