-1

I found an image online (https://i.stack.imgur.com/y1oT4.png) and I'm trying to take the sun and sky and make them rotate around the center of the screen, such that the sun and its rays appear to be spinning.

I intend to use a timer to control the movement, but I can't figure out how to rotate by an arbitrary angle. In other words, I know how to rotate by increments of 90 (switch the width and height), but what I'm trying to do is group a set of objects and rotate them around a single point.

I've looked around and found the AffineTransform() method, but I can't figure out if this is really what I need or how to use it if it is.

EDIT: Does this solve my problem? How to rotate Graphics in Java I will try it and update.

EDIT: It got me closer, but did not fix it. It returns this runtime error:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at FallScene.rotateBack(FallScene.java:77)
    at SceneDriver$1TimerListener.actionPerformed(SceneDriver.java:66)
    at javax.swing.Timer.fireActionPerformed(Timer.java:312)
    at javax.swing.Timer$DoPostEvent.run(Timer.java:244)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDo
    main.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre
    ad.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.
    java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
    ad.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
    Press any key to continue...

The call at FallScene.rotateBack(FallScene.java:77) is:

    bg.rotate(Math.toRadians(deg));

...which goes to:

public void paintComponent(Graphics g) 
{
    super.paintComponent(g);

    // Get the size of the component window
    int w = getWidth();
    int h = getHeight();

    // The Graphics2D object for the BACKGROUND
    Graphics2D bg = (Graphics2D)g;          

    // Sun
    Color solarYellow = new Color(255, 218, 0);
    bg.setPaint(solarYellow);
    Ellipse2D.Double sun = new Ellipse2D.Double((w / 2) - 150, (h / 2) - 150, 300, 300);
    bg.fill(sun); bg.draw(sun);
}
Community
  • 1
  • 1

1 Answers1

0

If you still need it, I think this operational and commented code should help you understand how to draw it.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.util.TimerTask;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class SunRotate extends JComponent
{  
    public static void main(String[] args) {
        final SunRotate sunRotate = new SunRotate(45);
        JFrame f = new JFrame();
        f.setContentPane(sunRotate);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setSize(new Dimension(800, 600));
        f.setVisible(true);
        new java.util.Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                sunRotate.deltaAngle(.3f);
                sunRotate.repaint();
            }
        }, 16, 16); // every 16 milliseconds
    }


    private float angle;

    public void deltaAngle(float delta) {
        angle += delta;
    }

    public SunRotate(float angle) {
        this.angle = angle;
    }

    public void paintComponent(Graphics g)
    {  
        super.paintComponent(g);

        int w = getWidth();
        int h = getHeight();

        // Recover Graphics2D 
        Graphics2D g2 = (Graphics2D) g;

        // Move and rotate
        g2.translate(w/2.0, h/2.0);
        g2.rotate(Math.toRadians(angle));


        // draw around 0,0
        Color solarYellow = new Color(255, 218, 0);
        g2.setPaint(solarYellow);
        Ellipse2D.Double sun = new Ellipse2D.Double( -150, -150, 300, 300);
        g2.fill(sun);
        { // draw some rays because the sun is round so we don't see the rotation
            // make a ray (triangle)
            Path2D ray = new Path2D.Float();
            ray.moveTo(0, 0);
            ray.lineTo(1000, 50);
            ray.lineTo(1000, -50);
            ray.closePath();
            // draw N rays, rotating each time
            int N = 20;
            for (int i = 0; i < N; i++) {
                g2.fill(ray);
                g2.rotate(Math.PI * 2 / N);
            }
        }
    }

}
Rémi
  • 679
  • 3
  • 7