Butterflies.java
From CompSciWiki
/****************************************************************************** * Butterflies * * Copyright 2009 by Samuel Pauls * * www.samuelpauls.com * * * * A screensaver that draws a rose and Temple H. Fay's butterfly curve. * * * * Permission is granted to distribute and modify this program, as long as * * you attribute changes to yourself and give others credit where due. No * * warranty is provided. * ******************************************************************************/ import java.awt.Color; import java.awt.Graphics; import javax.swing.JOptionPane; public class Butterflies extends Screensaver { public static void main (String[] args) { // args contains arguments passed to the program as it starts. For example, // if the screensaver is run as "java Butterflies /c", args[0] will contain // the first argument, "/c". if (args.length > 0 && args[0].startsWith ("/c")) { // Show an about dialog in the place of screensaver options. final String TITLE = "About Butterflies"; final String MESSAGE = "Butterflies\n" + "Copyright 2009 by Samuel Pauls\n" + "www.samuelpauls.com\n" + "\n" + "A screensaver that draws a rose and Temple H. Fay's butterfly" + " curve.\n" + "\n" + "Permission is granted to distribute and modify this program, as long" + " as\n" + "you attribute changes to yourself and give others credit where due." + " No\n" + "warranty is provided.\n"; JOptionPane.showMessageDialog (null, MESSAGE, TITLE, JOptionPane.INFORMATION_MESSAGE); } else if (args.length > 0 && args[0].startsWith ("/p")) { // Do nothing when a preview is requested for the monitor in Windows' // screensaver dialog. } else { // Start the screensaver. final int SECONDS = 1; setFrameDelay (SECONDS); new Butterflies(); } } // Draw a frame of this screensaver. public void drawFrame (Graphics g) { // Clear the background to black. g.setColor (Color.BLACK); g.fillRect (0, 0, getWidth(), getHeight()); // Setup the transformation values of the object. double scale = random (60, 400); double radius = scale / 2.0; double centerX = random (radius, getWidth() - radius); double centerY = random (radius, getHeight() - radius); // Choose a random color for the object. float red = (float)Math.random(); float green = (float)Math.random(); float blue = (float)Math.random(); g.setColor (new Color (red, green, blue)); // Draw an object. if (Math.random() < 0.5) { drawButterfly (g, scale, centerX, centerY); } else { drawRose (g, scale, centerX, centerY); } } // Return a random number within the specified inclusive range. public static double random (double minimum, double maximum) { final double RANGE = maximum - minimum; return minimum + Math.random() * RANGE; } // Draw Temple H. Fay's butterfly curve. public static void drawButterfly (Graphics g, double scale, double centerX, double centerY) { // Draw many of the points along the curve. for (double t = 0; t < 2 * Math.PI; t = t + 0.001) { // Exchange the t value for x and y points on the butterfly curve. double cache = (Math.exp (Math.cos (t)) - 2 * Math.cos (4 * t) - Math.pow (Math.sin (t / 12), 5)); double x = Math.sin (t) * cache; double y = Math.cos (t) * cache; // At this point, the butterfly is upside down. Flip it about the x-axis. y = y * -1; // Normalize the butterfly's size to a 1x1 rectangle. // This simplifies the code needed to randomly place the object on the // screen, such that it doesn't go over an edge. x = x / 6; y = y / 6; drawPoint (g, x, y, scale, centerX, centerY); } } // Draw a rose. public static void drawRose (Graphics g, double scale, double centerX, double centerY) { // Draw many of the points along the curve. for (double t = 0; t < 2 * Math.PI; t = t + 0.001) { // Exchange the t value for x and y points on the rose. double cache = Math.sin (2 * t); double x = Math.sin (t) * cache; double y = Math.cos (t) * cache; // Normalize the rose's size to a 1x1 rectangle. // This simplifies the code needed to randomly place the object on the // screen, such that it doesn't go over an edge. x = x / 2; y = y / 2; drawPoint (g, x, y, scale, centerX, centerY); } } // Draw a point of a scaled and translated object. public static void drawPoint (Graphics g, double x, double y, double scale, double centerX, double centerY) { // Scale the point. x = x * scale; y = y * scale; // Translate the point. x = x + centerX; y = y + centerY; // Draw the point as a circle to give the eventual line some thickness. final int DIAMETER = 4; g.fillOval ((int)x, (int)y, DIAMETER, DIAMETER); } } // Butterflies