CS 100: Programming Assignment P4
Solution
public class Date { // An instance of this class is a particular date. private String month; private int day; private int year; // "Moon" constants. // T is the average time (in days) between new Moons. public static final double T = 29.530588; // 29 days + 12 hours + 44 minutes + 2.8 seconds // tBase is the time (in days) since the last new Moon at the (GMT) start of January 1, 1600. public static final double tBase = 14.532069; // Constructor. Creates a Date object with month s, day d, and year y. public Date(String s, int d, int y) { month = s; day = d; year = y; } // Yields the relative index of this date. // (Days are indexed from 1 starting with January 1.) public int relDayIndex() { int s; if (month.equals("January")) s = day; else if (month.equals("February")) s = day+31; else if (month.equals("March")) s = day+59; else if (month.equals("April")) s = day+90; else if (month.equals("May")) s = day+120; else if (month.equals("June")) s = day+151; else if (month.equals("July")) s = day+181; else if (month.equals("August")) s = day+212; else if (month.equals("September")) s = day+243; else if (month.equals("October")) s = day+273; else if (month.equals("November")) s = day+304; else s = day+334; // Make leap year adjustment. boolean marchOrLater = !(month.equals("January") || month.equals("February")); if (leapYear(year) && marchOrLater) return s+1; else return s; } // Yields a string that specifies this date. public String prettyDate() {return month + " " + day + ", " + year;} // Yields true if y is a leap year. public static boolean leapYear(int y) { if (y%100==0) return (y%400==0); else return (y%4==0); } // Yields the absolute index of this date. // (Days are indexed from 1 starting with January 1, 1600.) public int absDayIndex() { int s=0; for(int y=1600;y<=year-1;y++) { if (leapYear(y)) s = s+366; else s = s+365; } s = s + relDayIndex(); return s; } // Yields the number of days since the "base" new moon. public double sinceBaseNewMoon() { return (absDayIndex() + tBase - 1); } // Yields true if the Moon is waxing t days after a new Moon. public static boolean isWaxing(double t) { double whatsLeft = t - Math.floor(t/T)*T; return (whatsLeft <= T/2); } } // Checks the methods leapYear, prettyDate, and relDayIndex. import java.io.*; public class P4A { public static void main(String args[]) { TokenReader in = new TokenReader(System.in); // Print the leap years from 1892 to 2012. System.out.println("Leap years during 1892-2012:\n"); int count=0; for (int yr=1892;yr<=2012;yr++) { if (Date.leapYear(yr)) { System.out.print(" " + yr); count++; if (count%10==0) System.out.println(""); } } // Display the relative day indices for the first of each month // during year y. int y = 1996; Date D; System.out.println("\nSome relative day indices:\n"); D = new Date("January",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("February",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("March",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("April",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("May",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("June",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("July",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("August",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("September",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("October",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("November",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); D = new Date("December",1,y); Format.println(System.out," %3d = " + D.prettyDate(),D.relDayIndex()); in.waitUntilEnter(); } } /* Output: Leap years during 1892-2012: 1892 1896 1904 1908 1912 1916 1920 1924 1928 1932 1936 1940 1944 1948 1952 1956 1960 1964 1968 1972 1976 1980 1984 1988 1992 1996 2000 2004 2008 2012 Some relative day indices: 1 = January 1, 1996 32 = February 1, 1996 61 = March 1, 1996 92 = April 1, 1996 122 = May 1, 1996 153 = June 1, 1996 183 = July 1, 1996 214 = August 1, 1996 245 = September 1, 1996 275 = October 1, 1996 306 = November 1, 1996 336 = December 1, 1996 */ // Checks the methods absDayIndex and elapsed. import java.io.*; public class P4B { public static void main(String args[]) { TokenReader in = new TokenReader(System.in); System.out.println("\nSome Absolute Day Indices:\n"); Date D1 = new Date("July",4,1776); Date D2 = new Date("August",27,1998); Date D3 = new Date("March",11,1999); D3 = new Date("January",9,1997); Format.println(System.out,"%8d = " + D1.prettyDate(),D1.absDayIndex()); Format.println(System.out,"%8d = " + D2.prettyDate(),D2.absDayIndex()); Format.println(System.out,"%8d = " + D3.prettyDate(),D3.absDayIndex()); System.out.println("\nThe associated values of sinceBaseNewMoon:\n"); double t1 = D1.sinceBaseNewMoon(); Format.println(System.out,"%14.4f = " + D1.prettyDate(),t1); double t2 = D2.sinceBaseNewMoon(); Format.println(System.out,"%14.4f = " + D2.prettyDate(),t2); double t3 = D3.sinceBaseNewMoon(); Format.println(System.out,"%14.4f = " + D3.prettyDate(),t3); System.out.println("\nWaxing or Waning?:\n"); if (Date.isWaxing(t1)) { System.out.println("The Moon is waxing on " + D1.prettyDate()); } else { System.out.println("The Moon is waning on " + D1.prettyDate()); } if (Date.isWaxing(t2)) { System.out.println("The Moon is waxing on " + D2.prettyDate()); } else { System.out.println("The Moon is waning on " + D2.prettyDate()); } if (Date.isWaxing(t3)) { System.out.println("The Moon is waxing on " + D3.prettyDate()); } else { System.out.println("The Moon is waning on " + D3.prettyDate()); } in.waitUntilEnter(); } } /* Output: Some Absolute Day Indices: 64469 = July 4, 1776 145606 = August 27, 1998 145011 = January 9, 1997 The associated values of sinceBaseNewMoon: 64482.5321 = July 4, 1776 145619.5321 = August 27, 1998 145024.5321 = January 9, 1997 Waxing or Waning?: The Moon is waning on July 4, 1776 The Moon is waxing on August 27, 1998 The Moon is waning on January 9, 1997 */ import java.awt.*; public class MoonPhase extends Frame { // Graphics g draws a moon with t-value t0. // The center is at (hc,vc) and the radius is r. public static void drawMoon(Graphics g, int hc, int vc, int r, double t0) { // Draw a darkened moon and set the "ink" to the chosen illumination color. g.setColor(Color.black); g.fillOval(hc-r,vc-r,2*r,2*r); g.setColor(Color.yellow); double dh; // Half the length of the current "coloring" line segment". int hLeft; // Left endpoint of the current "coloring" line segment". int hRight; // Right endpoint of the current "coloring" line segment". // Illuminate the moon by drawing appropriately colored horizontal line segments. for(int v=vc+r;v>=vc-r;v=v-1) { // Draw the illumination line segment having vertical component v. dh = Math.sqrt(r*r-(v-vc)*(v-vc)); // Its endpoints depend on whether the moon is in the first or second half // of its revolution. if (Date.isWaxing(t0)) { // Between new moon and full moon so the illumination is in the "right" half. hLeft = (int) (hc + Math.cos(2*Math.PI*t0/Date.T)*dh); hRight = (int) (hc + dh); } else { // Between full moon and new moon so the illumination is in the "left" half. hLeft = (int) (hc - dh); hRight = (int) (hc - Math.cos(2*Math.PI*t0/Date.T)*dh); } g.drawLine(hLeft,v,hRight,v); } } // Graphics g draws a moon row. // A moon row is a horizontal row of 7 moons all with radius r. // The leftmost moon has center (hc,vc). // The moon centers all have vertical component vc. // The center-to-center spacing of the moons equals 3*r. // Left-to-right the moons have t-values equal to t0,t0+1,...,t0+6 respectively. public static void drawWeekOfMoons(Graphics g, int hc, int vc, int r, double t0) { int h; // The horizontal coordinate of the current moon. double t; // The t-value of the current moon. h = hc; t = t0; for(int k=1;k<=7;k++) { drawMoon(g,h,vc,r,t); t++; h=h+3*r; } } // Graphics g draws 5 moon rows. // All moons have radius r. // The leftmost moon of the top moon row has center (hc,vc). // The vertical spacing of the moon rows is 3*r. // Top to bottom, the leftmost moons in each moon row have t-values equal to // t0,t0+7,t0+14,t0+21,and t0+28 respectively. public static void drawMonthOfMoons(Graphics g, int hc, int vc, int r, double t0) { int v; // The vertical coordinate of the current moon row. double t; // The t-value of the leftmost moon in the current moon row. v = vc; t = t0; for(int k=1;k<=5;k++) { drawWeekOfMoons(g,hc,v,r,t); t=t+7; v=v+3*r; } } public void paint(Graphics g) { // drawMoon(g,300,300,100,10); // drawMoon(g,600,300,100,20); // drawWeekOfMoons(g,100,200,30,0.0); // drawWeekOfMoons(g,100,300,30,16.0); // drawMonthOfMoons(g,100,100,30,0.0); // Date D = new Date("December", 25, 1776); // Washington crosses the Delaware // Date D = new Date("June",6,1944); // D-Day // Date D = new Date("July",20,1969); // Man on Moon Date D = new Date("February",21,1999); double t0 = D.sinceBaseNewMoon(); drawMonthOfMoons(g,100,100,30,t0); g.setFont(new Font("TimesRoman",Font.BOLD,24)); g.setColor(Color.black); String s = D.prettyDate(); g.drawString(s,300,550); } } public class P4C { public static void main(String args[]) { MoonPhase d = new MoonPhase(); d.resize(800,600); d.move(0,75); d.setTitle("Moons"); d.show(); d.toFront(); } }