
// Spirograph.java
// Robert Sedgewick and Kevin Wayne
// suggested by Diego Nehab
// Slightly reformatted by Andrew Davison, Nov. 2022

// https://introcs.cs.princeton.edu/java/15inout/Spirograph.java.html

/* A spirograph (technically, an epicycloid) is a curve formed by
   rolling a smaller circle of radius r inside
   a larger circle or radius R. If the pen offset of the pen point in
   the moving circle is a, then the equation of the resulting curve
   at time t is
 
      x = (R+r)*cos(t) - (r+a)*cos(((R+r)/r)*t)
      y = (R+r)*sin(t) - (r+a)*sin(((R+r)/r)*t)
      (moving circle outside the fixed circle)

      x = (R-r)*cos(t) + (r-a)*cos(((R-r)/r)*t)
      y = (R-r)*sin(t) - (r-a)*sin(((R-r)/r)*t)
      (moving circle inside the fixed circle) 
      
   Such curves were popularized by a best-selling toy that contains 
   discs with gear teeth on the edges and small holes that you could 
   put a pen in to trace spirographs. 

   Usage:
     > compile Spirograph.java
     > run Spirograph R r a
   e.g.
     > run Spirograph 180 40 15
     > run Spirograph 100 55 20

   Reference: http://www.math.dartmouth.edu/~dlittle/java/SpiroGraph
   Reference: http://www.wordsmith.org/~anu/java/spirograph.html
   https://nathanfriend.io/inspiral-web/
*/


public class Spirograph
{

  public static void main(String[] args)
  {
    if (args.length != 3) {
      System.out.println("Usage: run Spirograph <big radius> <small radius> <pen offset>");
      return;
    }

    double R = Double.parseDouble(args[0]);
    double r = Double.parseDouble(args[1]);
    double a = Double.parseDouble(args[2]);

    StdDraw.setXscale(-300, +300);
    StdDraw.setYscale(-300, +300);

    StdDraw.circle(0, 0, R);
    StdDraw.circle(0, 0, r);

    StdDraw.setPenColor(StdDraw.RED);
    for (double t = 0.0; t < 100; t += 0.01) {
      // moving r circle outside the fixed R circle
      double x = (R+r) * Math.cos(t) - (r+a) * Math.cos(((R+r)/r)*t);
      double y = (R+r) * Math.sin(t) - (r+a) * Math.sin(((R+r)/r)*t);

      StdDraw.point(x, y);
    }
    System.out.println("Drawing finished");
  } /* main */


}  // end of Spirograph class
