SHARE
TWEET

Nick Dunn

a guest Feb 2nd, 2010 1,153 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package solarsystem;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Dimension;
  5. import java.awt.GradientPaint;
  6. import java.awt.Graphics;
  7. import java.awt.Graphics2D;
  8. import java.util.Observable;
  9. import java.util.Observer;
  10. import java.util.Random;
  11. import javax.swing.JComponent;
  12. import javax.swing.JFrame;
  13. import javax.swing.JPanel;
  14. import javax.swing.JSlider;
  15. import javax.swing.event.ChangeEvent;
  16. import javax.swing.event.ChangeListener;
  17.  
  18. /**
  19.  *
  20.  * @author NDUNN
  21.  * @date Jan 29, 2010
  22.  */
  23. public class SolarSystemView extends JComponent implements Observer {
  24.  
  25.     // Make the sun this proportion of screen DEFAULT_WIDTH
  26.     private static final double SUN_RADIUS_PROPORTION = 0.2;
  27.     private static final double EARTH_RADIUS_PROPORTION = .3 * SUN_RADIUS_PROPORTION;
  28.     private static final double MOON_RADIUS_PROPORTION = .2 * EARTH_RADIUS_PROPORTION;
  29.  
  30.     private static final double EARTH_DISTANCE_PROPORTION_SCREEN = 0.4;
  31.     private static final double MOON_DISTANCE_PROPORTION_SCREEN = 0.1;
  32.  
  33.     private static final int DEFAULT_WIDTH = 640;
  34.     private static final int DEFAULT_HEIGHT = 640;
  35.  
  36.     private static final int NUM_STARS = 100;
  37.     private static final int MAX_STAR_RADIUS = 3;
  38.  
  39.     private static final double TWO_PI = 2.0 * Math.PI;
  40.  
  41.     private SolarSystemModel model;
  42.     private Random random = new Random();
  43.  
  44.     private int[] starX;
  45.     private int[] starY;
  46.     private int[] starRadius;
  47.    
  48.     public SolarSystemView(SolarSystemModel model) {
  49.         super();
  50.         this.model = model;
  51.         setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
  52.  
  53.         createStarField(DEFAULT_WIDTH, DEFAULT_HEIGHT, MAX_STAR_RADIUS);
  54.     }
  55.  
  56.     /**
  57.      * Creates and populates our arrays of star x values, star y values, and
  58.      * star radii
  59.      * @param width     what is max x value we should consider for star
  60.      * @param height    what is max y value we should consider for star
  61.      */
  62.     private void createStarField(int width, int height, int maxRadius) {
  63.         // Create the arrays
  64.         starX = new int[NUM_STARS];
  65.         starY = new int[NUM_STARS];
  66.         starRadius = new int[NUM_STARS];
  67.         // Fill them in with random values
  68.         for (int i = 0; i < NUM_STARS; i++) {
  69.             starX[i] = random.nextInt(width);
  70.             starY[i] = random.nextInt(height);
  71.             starRadius[i] = random.nextInt(maxRadius);
  72.         }
  73.     }
  74.  
  75.  
  76.     /**
  77.      * Draws a black backdrop with star field
  78.      * @param g2
  79.      */
  80.     private void drawSpaceBackdrop(Graphics2D g2) {
  81.         // Draw background as black
  82.         g2.setColor(Color.BLACK);
  83.         g2.fillRect(0, 0, getWidth(), getHeight());
  84.  
  85.         g2.setColor(Color.WHITE);
  86.         for (int i = 0; i < NUM_STARS; i++) {
  87.             g2.fillOval(starX[i], starY[i], starRadius[i], starRadius[i]);
  88.         }
  89.        
  90.     }
  91.  
  92.     /**
  93.      *
  94.      * @param g2 graphics context with (0,0) in center of screen (where sun will
  95.      * be centered)
  96.      */
  97.     private void drawSun(Graphics2D g2) {
  98.         int sunRadius = (int) (SUN_RADIUS_PROPORTION * getWidth());
  99.         GradientPaint sunColor = new GradientPaint(0, 0, Color.YELLOW, 0, sunRadius, Color.RED);
  100.         g2.setPaint(sunColor);
  101.         g2.fillOval(-sunRadius/2, -sunRadius/2, sunRadius, sunRadius);
  102.     }
  103.  
  104.  
  105.  
  106.     /**
  107.      * Draws the earth to the screen, whose position is dependent upon the
  108.      * day of the year
  109.      * @param g2 the graphics context with its origin in the center of the sun
  110.      */
  111.     private void drawEarth(Graphics2D g2) {
  112.         // Draw the earth
  113.         // Calculate what portion along its orbit the earth is, and thus how
  114.         // far to rotate about our centerpoint
  115.         double earthTheta = map(model.getDay(), 0, SolarSystemModel.DAYS_PER_EARTH_REVOLUTION_AROUND_SUN, 0, TWO_PI);
  116.  
  117.         // Rotate our coordinate system by that much
  118.         g2.rotate(earthTheta);
  119.         // Translate the earth
  120.         int distanceFromEarthToSun = (int) (EARTH_DISTANCE_PROPORTION_SCREEN * getWidth());
  121.         g2.translate(distanceFromEarthToSun, 0);
  122.  
  123.         int earthRadius = (int) (EARTH_RADIUS_PROPORTION * getWidth());
  124.         GradientPaint earthColor = new GradientPaint(0, 0, Color.BLUE, 0, earthRadius, Color.GREEN.darker(), true);
  125.         g2.setPaint(earthColor);
  126.  
  127.         g2.fillOval(-earthRadius/2, -earthRadius/2, earthRadius, earthRadius);
  128.     }
  129.  
  130.     /**
  131.      * Draw the moon to the screen, whose position is dependent upon that of
  132.      * the earth and the day of the year, which dictates its position along
  133.      * its orbit around earth
  134.      * @param g2 the graphics context with its origin in the center of the earth
  135.      */
  136.     private void drawMoon(Graphics2D g2) {
  137.         double moonTheta = map(model.getDay(), 0, SolarSystemModel.DAYS_PER_MOON_ORBIT_AROUND_EARTH, 0, TWO_PI);
  138.  
  139.         int moonRadius = (int) (MOON_RADIUS_PROPORTION * getWidth());
  140.         g2.setColor(Color.WHITE);
  141.         g2.rotate(moonTheta);
  142.         int distanceFromEarthToMoon = (int) (MOON_DISTANCE_PROPORTION_SCREEN * getWidth());
  143.         // Translate the earth
  144.         g2.translate(distanceFromEarthToMoon, 0);
  145.         g2.fillOval(-moonRadius/2, -moonRadius/2, moonRadius, moonRadius);
  146.     }
  147.  
  148.  
  149.     @Override
  150.     public void paintComponent(Graphics g) {
  151.         Graphics2D g2 = (Graphics2D) g;
  152.  
  153.         drawSpaceBackdrop(g2);
  154.  
  155.         // Set the origin to be in the center of the screen
  156.         g2.translate(getWidth()/2, getHeight()/2);
  157.  
  158.         // Order matters, since the earth placement is dependent upon the sun
  159.         // placement, and the moon placement is dependent upon the earth placement
  160.         drawSun(g2);
  161.  
  162.         drawEarth(g2);
  163.  
  164.         drawMoon(g2);
  165.     }
  166.  
  167.     public static void main(String[] args) {
  168.         JFrame frame = new JFrame("Solar System");
  169.  
  170.         final SolarSystemModel model = new SolarSystemModel();
  171.         final SolarSystemView view = new SolarSystemView(model);
  172.         model.addObserver(view);
  173.  
  174.         JPanel panel = new JPanel();
  175.         panel.add(view);
  176.  
  177.         final JSlider daySlider = new JSlider(0,SolarSystemModel.DAYS_PER_EARTH_REVOLUTION_AROUND_SUN);
  178.         daySlider.setPaintLabels(true);
  179.         daySlider.setPaintTicks(true);
  180.         daySlider.setMajorTickSpacing(100);
  181.         panel.add(daySlider);
  182.         daySlider.addChangeListener(new ChangeListener() {
  183.             public void stateChanged(ChangeEvent e) {
  184.                 model.setDay(daySlider.getValue());
  185.             }
  186.         });
  187.         frame.add(panel);
  188.  
  189.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  190.         frame.pack();
  191.         frame.setVisible(true);
  192.     }
  193.  
  194.  
  195.     public void update(Observable o, Object arg) {
  196.         repaint();
  197.     }
  198.  
  199.  
  200.     /**
  201.      * @param value The incoming value to be converted
  202.      * @param low1  Lower bound of the value's current range
  203.      * @param high1 Upper bound of the value's current range
  204.      * @param low2  Lower bound of the value's target range
  205.      * @param high2 Upper bound of the value's target range
  206.      */
  207.     public static final double map(double value, double low1, double high1, double low2, double high2) {
  208.  
  209.         double diff = value - low1;
  210.         double proportion = diff / (high1 - low1);
  211.  
  212.         return lerp(low2, high2, proportion);
  213.     }
  214.  
  215.     // Linearly interpolate between two values
  216.     public static final double lerp(double value1, double value2, double amt) {
  217.         return ((value2 - value1) * amt) + value1;
  218.     }
  219.  
  220.    
  221.  
  222. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top