3.2   Creating Data Types


In this section, we introduce the Java mechanism that enables us to create user-defined data types. We consider a range of examples, from charged particles and complex numbers to turtle graphics and stock accounts.

Basic elements of a data type.

Coulomb's law To illustrate the process, we define in Charge.java a data type for charged particles. Coulomb’s law tells us that the electric potential at a point \((x, y)\) due to a given charged particle is \(V = kq /r\), where \(q\) is the charge value, \(r\) is the distance from the point \((x, y)\) to the charge, and \(k = 8.99 \times 10^9\) is the electrostatic constant. In summary, to define a data type in a Java class, you need instance variables, constructors, instance methods, and a test client.

Anatomy of a class

Stopwatch.

Stopwatch.java implements the following API:

Stopwatch API
It is a stripped-down version of an old-fashioned stopwatch. When you create one, it starts running, and you can ask it how long it has been running by invoking the method elapsedTime().

Histogram.

Histogram Histogram.java is a data type to visualize data using a familiar plot known as a histogram. For simplicity, we assume that the data consists of a sequence of integer values between 0 and n−1. A histogram counts the number of times each value appears and plots a bar for each value (with height proportional to its frequency). The following API describes the operations:

Histogram API

Turtle graphics.

Turtle.java is a mutable type for turtle graphics, in which we command a turtle to move a specified distance in a straight line, or rotate (counterclockwise) a specified number of degrees.
Turtle graphics API
Here are a few example clients:

Complex numbers.

A complex number is a number of the form x + iy, where x and y are real numbers and i is the square root of −1. The basic operations on complex numbers are to add and multiply them, as follows: Complex.java is an immutable data type that implements the following API:

Complex number API
This data type introduces a few new features.

Mandelbrot set.

The Mandelbrot set is a specific set of complex numbers with many fascinating properties. The algorithm for determining whether or not a complex number \(z_0\) is in the Mandelbrot set is simple: Consider the sequence of complex numbers \(z_0, z_1, z_2, \ldots, z_t, \ldots,\) where \(z_{i+1} = z_i^2 + z_0\). For example, the following table shows the first few entries in the sequence corresponding to \(z_0 = 1 + i\):

Mandelbrot sequence
Now, if the sequence \( | z_i |\) diverges to infinity, then \(z_0\) is not in the Mandelbrot set; if the sequence is bounded, then \(z_0\) is in the Mandelbrot set. For many points, the test is simple; for many other points, the test requires more computation, as indicated by the examples in the following table:

Mandelbrot sequences
To visualize the Mandelbrot set, we define an evenly spaced n-by-n pixel grid within a specified square and draw a black pixel if the corresponding point is in the Mandelbrot set and a white pixel if it is not.

Mandelbrot set

But how do we determine whether a complex number is in the Mandelbrot set? For each complex number, Mandelbrot.java computes up to 255 terms in its sequence. If the magnitude ever exceeds 2, then we can conclude that the complex number is not in the set (because it is known that the sequence will surely diverge). Otherwise, we conclude that the complex number is in the set (knowing that our conclusion might be wrong on occasion).

Commercial data processing.

StockAccount.java implements a data type that might be used by a financial institution to keep track of customer information.

Stock account API


Exercises

  1. Develop an implementation Rectangle.java of your Rectangle API from Exercise 3.2.1 that that represents rectangles with the x- and y-coordinates of their lower-left and upper-right corners. Do not change the API.
  2. Implement a data type Rational.java numbers that supports addition, subtraction, multiplication, and division.

    Rational API
  3. Write a data type Interval.java that implements the following API:

    Interval API
    An interval is defined to be the set of all points on the line greater than or equal to min and less than or equal to max. In particular, an interval with max less than min is empty. Write a client that is a filter that takes a floating-point command-line argument x and prints all of the intervals on standard input (each defined by a pair of double values) that contain x.
  4. Write a data type Point.java that implements the following API:

    Point API
  5. Modify the toString() method in Complex.java so that it complex numbers in the traditional format. For example, it should print the value \(3-i\) as 3 - i instead of 3.0 + -1.0i, the value 3 as 3 instead of 3.0 + 0.0i and the value \3i\) as 3i instead of 0.0 + 3.0i.
  6. Write a Complex client RootsOfUnity.java that takes two double values a and b and an integer n from the command line and prints the nth root of \(a + bi\).
  7. Implement the following additions to Complex.java:

    Complex API

    Write a test client that exercises all of your methods.

  8. Suppose you want to add a constructor to Complex.java that takes a double value as its argument and creates a Complex number with that value as the real part (and no imaginary part). You write the following code:
    public void Complex(double real) {
        re = real;
        im = 0.0;
    }
    
    But then the statement Complex c = new Complex(1.0); does not compile. Why?

    Solution: Constructors do not have return types, not even void. This code defines method named Complex(), not a constructor. Remove the keyword void.

Creative Exercises

  1. Electric potential visualization. Write a program Potential.java that creates an array of charged particles from values given on standard input (each charged particle is specified by its x-coordinate, y-coordinate, and charge value) and produces a visualization of the electric potential in the unit square. To do so, sample points in the unit square. For each sampled point, compute the electric potential at that point (by summing the electric potentials due to each charged particle) and plot the corresponding point in a shade of gray proportional to the electric potential.

    Electric potential          Electric potential


  2. Quaternions. In 1843, Sir William Hamilton discovered an extension to complex numbers called quaternions. Quaternions extend the concept of rotation in three dimensions to four dimensions. They are used in computer graphics, control theory, signal processing, and orbital mechanics, e.g., command for spacecraft attitude control systems. are related to Pauli spin matrices in physics. Create a date type Quaternion.java to represent quaternions. Include operations for adding, multiplying, inverting, conjugating, and taking the norm of quaternions.

    A quaternion can be represented by a 4-tuple of real numbers \((a_0, a_1, a_2, a_3)\), which represents \(a_0 + a_1 i + a_2 j + a_3 k\). The fundamental identity is \(i^2 = j^2 = k^2 = ijk = -1\).

    • Magnitude: \( \left \| a \right \| = \sqrt{a_0^2 + a_1^2 + a_2^2 + a_3^2} \)
    • Conjugate: \( a^* = (a_0, -a_1, -a_2, -a_3)\)
    • Inverse: \( a^{-1} = (a_0\,/\, \left \| a \right \|^2, -a_1\,/\, \left \| a \right \|^2, -a_2\,/\, \left \| a \right \|^2, -a_3\,/\, \left \| a \right \|^2)\)
    • Sum: \( a + b = (a_0+b_0, a_1+b_1, a_2+b_2, a_3+b_3)\)
    • Hamilton product: $$ \begin{align} a \times b \; = \; (& a_0b_0 - a_1b_1 - a_2b_2 - a_3b_3, \\ & a_0b_1 + a_1b_0 + a_2b_3 - a_3b_2, \\ & a_0b_2 - a_1b_3 + a_2b_0 + a_3b_1, \\ & a_0b_3 + a_1b_2 - a_2b_1 + a_3b_0) \end{align} $$
    • Quotient: \( a\,/\,b = a^{-1} \times b \)
  3. Dragon curve. Write a program Dragon.java that reads in a command-line parameter N and plots the order N dragon curve using turtle graphics. The dragon curve was first discovered by three NASA physicists (John E. Heighway, Bruce A. Banks, and William G. Harter) and later popularized by Martin Gardner in Scientific American (March and April 1967) and Michael Crichton in Jurassic Park.

    This is a sophisticated program that uses two mutually recursive functions.

    Program SequentialDragon.java is an iterative version of the dragon curve. It is a hacker's paradise.

  4. Hilbert curves. A space-filling curve is a continuous curve in the unit square that passes through every point. Write a recursive Turtle client Hilbert.java (or SingleHilbert.java) that produces these recursive patterns, which approach a space-filling curve that was defined by the mathematician David Hilbert at the end of the 19th century.
    Hilbert curve of order 1 Hilbert curve of order 2 Hilbert curve of order 3 Hilbert curve of order 4 Hilbert curve of order 5
  5. Gosper island. Write a recursive Turtle client GosperIsland.java that produces these recursive patterns.
  6. Chaos with Newton's method. The polynomial \(f(z) = z^4 - 1\) has 4 roots at 1, −1, i, and −i. We can find the roots using Newton's method in the complex plane: \(z_{k+1} = z_k - f(z_k) \,/ \, f'(z_k)\). Here \(f(z) = z^4 - 1\) and \(f'(z) = 4z^3\). The method converges to one of the 4 roots depending on the starting point \(z_0\). Write a program NewtonChaos.java that takes a command-line argument n and creates an n-by-n image corresponding to the square of size 2 centered at the origin. Color each pixel white, red, green, or blue according to which of the four roots the corresponding complex number converges (black if no convergence after 100 iterations).

    Newton's method chaos
  7. Color Mandelbrot plot. Create a file of 256 integer triples that represent interesting Color values, and then use those colors instead of grayscale values to plot each pixel in ColorMandelbrot.java Read the values to create an array of 256 Color values, then index into that array with the return value of mand(). By experimenting with various color choices at various places in the set, you can produce astonishing images. See mandel.txt for an example.

    Mandelbrot set           Mandelbrot set
    -1.5 -1.0 2.0 2.0 0.10259 -0.641 0.0086 0.0086
  8. Julia sets. The Julia set for a given complex number c is a set of points related to the Mandelbrot function. Instead of fixing z and varying c, we fix c and vary z. Those points z for which the modified Mandelbrot function stays bounded are in the Julia set; those for which the sequence diverges to infinity are not in the set. All points z of interest lie in the 4-by-4 box centered at the origin. The Julia set for c is connected if and only if c is in the Mandelbrot set! Write a program ColorJulia.java that takes two command-line arguments a and b, and plots a color version of the Julia set for c = a + bi, using the color-table method described in the previous exercise.

    Julia set           Julia set
    -1.25 0.00 -0.75 0.10

Web Exercises

  1. IP addresses. Create a data type for IPv4 (Internet Protocol, version 4) addresses. An IP address is a 32-bit integer.
  2. Dates. Create a data type Date that represents a date. You should be able to create a new Date by specifying the month, day, and year. It should supports methods to compute the number of days between two dates, return the day of the week that a day falls on, etc.
  3. Time bombs. UNIX represents the date with a signed integer measuring the number of seconds since January 1, 1970. Write a client program to calculate when this date will occur. Add a static method add(Date d, int days) to your date data type that returns a new date which is the specified number of days after the date d. Note that there are 86,400 seconds in a day.
  4. Qubits. In quantum computing, a qubit plays the role of a bit. It is a complex number a + bi such that |a + bi| = 1. Once we measure a qubit, it "decides" to be a 1 with probability a2 and a 0 with probability b2. Any subsequent observations will always yield the same value. Implement a data type Qubit that has a constructor Qubit(a, b) and a boolean method observe that returns true or false with the proscribed probabilities.
  5. Biorhythms. A biorhythm is a pseudo-scientific profile of the three natural cycles of your body: physical (23 days), emotional (28 days), and intellectual (31 days). Write a program that takes six command line inputs M, D, Y, m, d, and y where (M, D, Y) is the month (1-12), day (1-31), and year (1900-2100) of your birthday and (m, d, y) is today's month, day, and year. It should then print out your biorhythm on a scale of -1.0 to 1.0 according to the formula: sin (2 π age / cycle length). Use the date data type created in the previous exercise.
  6. Particle. Create a data type for elementary or composite particles (electron, proton, quark, photon, atom, molecule). Each particle should have an instance variable to store its name, its mass, its charge, and its spin (multiple of 1/2).
  7. Quark. Quarks are the smallest known building blocks of matter. Create a data type for quarks. Include a field for its type (up, down, charm, strange, top, or bottom) and its color (red, green, or blue). The charges are +2/3, -1/3, +2/3, -1/3, +2/3, -1/3, respectively. All have spin 1/2.
  8. Biorhythms. Plot your biorhythm in turtle graphics over a 6 week interval. Identify critical days when your rhythm goes from positive to negative - according to biorhythm theory, this is when you are most prone to accident, instability, and error.
  9. Vector3. Include normal vector operations for 3-vectors, including cross product. The cross product of two vectors is another vector. a cross b = ||a|| ||b|| sin(theta) n, where theta is angle between a and b, and n is unit normal vector perpendicular to both a and b. (a1, a2, a3) cross (b1, b2, b3) = (a2 b3 - a3 b2, a3 b1 - a1 b3, a1 b2 - a2 b1). Note that |a cross b| = area of the parallelogram with sides a and b. Cross product arises in definition of torque, angular momentum and vector operator curl.
  10. Four-vector. Create a data type for four-vectors. A four-vector is a four-dimensional vector (t, x, y, z) subject to Lorentz transformations. Useful in special relativity.
  11. Euclidean points. Create a data type EuclideanPoint.java that represents a d-dimensional point. Include a method so that p.distanceTo(q) returns the Euclidean distance between points p and q.
  12. Vector field. A vector field associates a vector with every point in a Euclidean space. Widely used in physics to model speed and direction of a moving object or or strength and direction of a Newtonian force.
  13. Soda machine. Create a data type SodaMachine that has methods insertCoin(), getChange(), buy(), etc.
  14. Months. Write a data type Month that represents one of the twelve months of the year. It should have fields for the name of the month, the number of days in the month, and the birthstone.

    MONTH DAYS BIRTHSTONE
    January 31 Garnet
    February 28 Amethyst
    March 31 Aquamarine
    April 30 Diamond
    May 31 Emerald
    June 30 Alexandrite
    July 31 Ruby
    August 31 Peridot
    September 30 Sapphires
    October 31 Opal
    November 30 Topaz
    December 31 Blue Zircon


  15. Gauss multiplication. Implement complex multiplication using only 3 floating point multiplications (instead of 4). You may use as many as 5 floating point additions. Answer: Gauss gave the following method to multiply (a + bi)(c + di). Set x1 = (a + b)(c + d), x2 = ac, x3 = bd. Then the product is given by x + yi where x = x2 - x3, y = x1 - x2 - x3.
  16. Tensors. Create a data type for tensors.
  17. UN Countries. Create a data type Country for UN countries. Include fields for 3 digit UN Code, 3 letter ISO abbreviation, country name, and capital. Write a program Country.java that reads in a list of countries and stores them in an array of type Country. Use the method String.split to help parse the input file.
  18. Area codes. Create a data type for telephone area codes in North America. Include fields for the area code, the city, and state, and the two letter state abbreviation. Or for international phone codes. Include a field for zone, code, and country.
  19. Congressional districts. Create a data type for places, counties, and congressional districts. Include fields for place name, county name, county code, zip code, congressional district, etc. Use the data sets from the 1998 FIPS55-DC3 Index: Pennsylvania (2MB) or all 50 states plus DC and 9 outlying areas (30MB).
  20. Latitudes and longitudes. For USA latitudes and longitudes, use the TIGER database or www.bcca.org or gazetteer. For the rest of the world, use earth-info.
  21. Astronomy. Data for asteroids, meteors, and comets.
  22. Fortune 1000 companies. Create a data type the for Fortune 1000. Include fields for company name and sales revenue in millions of dollars. Data taken from April 15, 2002 issue of Fortune. Note: currently need to parse data.
  23. Molecular weight. Write a program so that the user enters a molecule H2 O and the program calculates its molecular weight.
  24. Some potentially useful datafiles: aroma therapies, nutritional information, meteorological glossary, psychiatric disorders, words translated in 15 languages, dictionary of emoticons, meanings of common names, World Almanac facts about countries.

  25. Student records. Create a data type Student.java to represent students in an introductory computer science course. Each student record object should represent a first name, last name, email address, and section number. Include a toString() method that returns a string representation of a student and a less() method that compares two students by section number.
  26. Impedance. Impedance is the generalization of resistance from DC circuits to AC circuits. In an AC circuit, the impedance of a component measures its opposition to the flow of electrons at a given frequency ω. The impedance has two components: the resistance and the reactance. The resistance R of a circuit component measures its opposition to the movement of electrons (friction against motion of electrons) when a given voltage is applied. The reactance X of a circuit component measures its ability to store and release energy as the current and voltage fluctuate (inertia against motion of electrons).

    In circuits with resistors only, the current is directly proportional to the voltage. However, with capacitors and inductors, there is a +- 90 degree "phase shift" between the current and voltage. This means that when the voltage wave is at its maximum, the current is 0, and when the current is at its maximum the voltage is 0. To unify the treatment of resistors (R), inductors (L), and capacitors (C) it is convenient to treat the impedance as the complex quantity Z = R + iX. the impedance of an inductor is iwL and the impedance of a capacitor is 1/iwC. To determine the impedance of a sequence of circuit elements in series, we simply add up their individual impedances. Two important quantities in electrical engineering are themagnitude of the impedance and the phase angle. The magnitude is the ratio of the RMS voltage to the RMS current - it equals the magnitude of the complex impedance. The phase angle is the amount by which the voltage leads or lags the current - it is the phase of the complex impedance. Program CircuitRLC.java does a computation involving complex numbers and impedance of circuits with resistors, inductors, and capacitors in series.

    Exercise: RLC circuit in parallel. 1/Z = 1/Z1 + 1/Z2 + ... 1/Zn.

    Exercise (for objects): repeat series-parallel network for RLC circuits with impedances instead of resistance

  27. Diffusion of particles in a fluid. Simulate diffusion of particles in a fluid. See BrownianParticle.java in Section 9.8.
  28. Electric field lines. Michael Faraday introduced an abstraction called electric field lines to visualize the electric field. By Coulombs law, the electric field at a point induced by a point charge qi is given by Ei = k qi / r2, and the direction points to qi if qi is negative and away from qi it is positive. If there are a group of n point charges, the electric field at a point is the vector sum of the electric fields induced by the n individual point charges. We can compute it by summing up the components in the x- and y- directions. The figure below illustrates the field lines for two equal positive point charges (left) and two point charges of opposite signs (right). The second configuration is called an electric dipole: the charges cancel each other out, and the electric field weakens very quickly as you move away from the charges. Examples of dipoles can be found in molecules where charge is not evenly distributed. Oscillating dipoles can be used to produce electromagnetic waves to transmit radio and television signals.

    Electric potential          Electric potential

    Program FieldLines.java draws 10 electric field lines coming out of each charge. (We take some liberties since traditionally the number of field lines per unit area should be proportional to the magnitude of the field strength.) Each line starts on a 1-pixel circle around the charge, at twelve equally spaced angles. The electric field at a point (x, y) from a point charge qi is given by Ei = k qi / r2, where qi is the magnitude of the charge i and r is the radial distance from it. The field due to several charges is the vector sum of the field due to each, and can be found by adding the x- and y-components. After calculating the electric field strength, we move in the direction of the vector field and draws a spot. We repeat this process until we reach the boundary of the region or another point charge. The figures below illustrate the electric potential and field lines for several random charges of equal magnitude.

    Electric potential and field lines          Electric potential and field lines          Electric potential and field lines
  29. Koch snowflake with rainbow of colors.

    The Koch snowflake of order n consists of three copies of the Koch curve of over n. We draw the three Koch curves one after the other, but rotate 120° clockwise in between. Below are the Koch snowflakes of order 0, 1, 2, and 3. Write a program KochRainbow.java that plots the Koch snowflake in a continuous spectrum of colors from red, to orange, yellow, green, blue, and indigo, and violet.

    Koch Snowflake Koch Snowflake Koch Snowflake Koch Snowflake Koch Snowflake
  30. Anti-Koch snowflakes. The anti-Koch snowflake is generated exactly like the Koch snowflake, except that clockwise and counterclockwise are interchanged. Write a program AntiKoch.java that takes a command line parameter N and plots the anti-Koch snowflake of order N using Turtle graphics.
  31. Randomized Koch snowflakes. A randomized Koch snowflake is generated exactly like the Koch snowflake, except that we flip a coin to generate the clockwise and counterclockwise direction at each step.
  32. Turtle graphics.
    1. Minkowski sausage. (Sausage.java)
    2. Cesaro broken square.
  33. More turtle graphics. Write a program to produce each of the following recursive patterns.
    1. Levy tapestry. (Levy.java)
    2. Fudgeflake.
  34. Turtle graphics (hard). Write a program to produce each of the following recursive patterns without lifting the pen or tracing over the same line segment more than once.
    1. Sierpinski arrowhead.
    2. Sierpinski curve.
  35. Mandelbrot trajectory. Write an interactive program Trajectory.java that plots the sequence of points in the Mandelbrot iteration in the complex plane. If the user clicks on (x, y), plot the sequence of iterates for z = x + iy.
  36. Faster Mandelbrot. Speed up Mandelbrot by performing the computation directly instead of using Complex. Compare. Incorporate periodicity checking or boundary tracing for further improvements. Use divide-and-conquer: choose 4 corners of a rectangle and a few random points inside; if they're all the same color, color the whole rectangle that color; otherwise divide into 4 rectangles and recur.
  37. Random walker. Write a data type RandomWalker that simulates the motion of a random walker in the plane that starts at the origin and makes a random step (left, right, up, or down) at each step. Include a method step() that moves the random walker one step and a method distance() that returns the distance the random walker is from the origin. Use this data type to formulate a hypothesis as to how far (as a function of N) the random walker is from the origin after N steps. (See also Exercise 1.x.)
  38. Big rational numbers. Create a data type BigRational.java for positive rational numbers, where the numerators and denominators can be arbitrarily large. Hint: use java.math.BigInteger
  39. Deluxe turtle graphics. Extend Turtle in various ways. Make DeluxeTurtle that adds color, etc. Add a version that supports error checking. For example, throw a TurtleOutOfBounds exception if turtle goes outside designated boundary.
  40. Write a program FourChargeClient.java that takes a double command-line argument r, creates four Charge objects that are each distance r from the center of the screen (0.5, 0.5), and prints the potential at location (0.25, 0.5) due to the combined four charges. All four charges should have the same unit charge.
  41. Why does program Bug1.java create a java.lang.NullPointerException when executed?
    public class Bug1 { 
       private String s;
       public void Bug1()       { s = "hello"; }
       public String toString() { return s.toUpperCase(); }
       public static void main(String[] args) {
          Bug1 x = new Bug1();
          StdOut.println(x);
       }
    }
    

    Answer: the programmer probably intended to make the no argument constructor set the string to hello. However, it has a return type (void) so it is an ordinary instance method instead of a constructor. It just happens to have the same name as the class.

  42. Why does program Bug2.java create a java.lang.NullPointerException when executed?
  43. Implement a data type Die for rolling a fair die, say with 6 sides. Include a mutator method roll() and an accessor method value.
  44. Implement a mutable data type LFSR for a linear feedback shift register.
  45. Implement a mutable data type Odometer.
  46. Complex trigonometric functions. Add methods to Complex.java support trigonometric and exponential functions on complex numbers.
    • \(\exp(a + ib) = e^a \cos(b) + i \, e^a \sin(b)\)
    • \(\sin(a + ib) = \sin(a) \cosh(b) + i \cos(a) \sinh(b)\)
    • \(\cos(a + ib) = \cos(a) \cosh(b) - i \sin(a) \sinh(b)\)
    • \(\tan(a + ib) = \sin(a + ib) \;/\; \cos(a + ib)\)
  47. Implement a data type VotingMachine for tabulating votes. Include mutator methods voteRepublican(), voteDemocrat(), and voteIndependent(). Include an accessor method getCount() to retrieve the total number of votes.
  48. What happens when you try to compile and execute the following code fragment?
    Student x;
    StdOut.println(x);
    

    Answer: it complains that x may not be initialized, and does not compile.

  49. What happens when you try to compile and execute the following code fragment?
    Student[] students = new Student[10];
    StdOut.println(students[5]);
    

    Answer: it compiles and prints out null.

  50. What is wrong with the following code fragment?
    int n = 17;
    Dog[] dogs = new Dog[n];
    for (int i = 0; i < n; i++) {
       dogs[i].bark();
       dogs[i].eat();
    }
    

    Answer: it produces a NullPointerException because we forgot use new to create each individual Dog object. To correct, add the following loop after the array initialization statement.

    for (int i = 0; i < n; i++)
       dogs[i] = new Dog();
    

  51. What does the following code fragment print?
    Complex c = new Complex(2.0, 0.0);
    StdOut.println(c);
    StdOut.println(c.mul(c).mul(c).mul(c));
    StdOut.println(c);
    
  52. What's wrong with the following code fragment that swaps the Student objects x and y?
    Student swap = new Student();
    swap = x;
    x = y;
    y = swap;
    

    Answer: First, the data type Student does not have a no-argument constructor. If it did, then it would technically be correct, but the new Student() line is unnecessary and wasteful. It allocates memory for a new student object, sets swap equal to that memory address, then immediately sets swap equal to the memory address of x. The allocated memory is no longer accessible. The following version is correct.

    Student swap = x;
    x = y;
    y = swap;
    
  53. Find inputs to the Mandelbrot update formula that make it converge (z0 = 1/2 + 0i), cycle with a period of 1 (z0 = -2 + 0i), cycle with a period of 2 (z0 = -1 + 0i), or stay bounded without converging (z0 = -3/2 + 0i).
  54. Point3D. Create a data type for points in 3 dimensional space. Include a constructor that takes three real coordinates x, y, and z. Include methods distance, distanceSquared, and distanceL1 for the Euclidean distance, Euclidean distance squared, and the L1-distance.
  55. Create a data type PhoneNumber.java that represents a US phone number. The constructor should take three string arguments, the area code (3 decimal digits), the exchange (3 decimal digits) and the extension (4 decimal digits). Include a toString method that prints out phone numbers of the form (800) 867-5309. Include a method so that p.equals(q) returns true if the phone numbers p and q are the same, and false otherwise.
  56. Redo PhoneNumber.java but implement it using three integer fields. Make the constructor take three integer arguments. Comment on the advantages and disadvantages of this approach over the string representation.

    Answer: more efficient with time and memory. More hassle to handle leading 0s correct in constructor and toString method.

  57. Write a program to draw the field lines for a uniform field. Arrange N evenly-spaced particles with charge e in a vertical column, and arrange N particles with charge -e in a vertical column so that each charge on one side is lined up with a corresponding charge on the other side. This simulates the field inside a plane capacitor. What can you say about the resulting electric field? A. Almost uniform.
  58. Equipotential surfaces. An equipotential surface is the set of all points that have the same electric potential V. Given a group of N point charges, it is useful to visualize the electric potential by plotting equipotential surfaces (aka contour plots). Program Equipotential.java draws a line every 5V by computing the potential at each gridpoint and checking whether the potential is within 1 pixel of a multiple of 5V. Since the electric field E measures how much the potential changes, E * eps is the range that the potential changes in a distance of 1 pixel. It relies on the helper program DeluxeCharge.java.

    Electric equipotential                Electric equipotential

    It is also interesting to plot the field lines and the equipotential lines simultaneously. The field lines are always perpendicular the the equipotential lines.

  59. Color palettes. Create Mandelbrot and Julia sets using different color palettes. For example, this scheme was proposed by Hubert Grassmann
    Color[] colors = new Color[ITERS];
    for (int t = 0; t < ITERS; t++) {
        // or some other primes
        int r = 13*(256-t) % 256;
        int g =  7*(256-t) % 256;
        int b = 11*(256-t) % 256;
        colors[t] = new Color(r, g, b);
    }
    
    and produces a striking image of the Julia set

    Julia set