
// DrawCircle.java
// Andrew Davison, ad@coe.psu.ac.th, April 2023

/* Inspired by the mathologer video:
    "Times Tables, Mandelbrot and the Heart of Mathematics"
    https://www.youtube.com/watch?v=qhbuKbxJsk8

   Usage:
     > compile DrawCircle.java
     > run DrawCircle <n>
   e.g.
     > run DrawCircle  100
*/

import java.awt.*;
import java.util.*;
import java.awt.geom.*;


public class DrawCircle
{
  private static final int NUM_PTS = 200;

  private static Color[] colors;
  private static int colCount = 0;


  public static void main(String[] args)
  {
    colors = generateRainbow(1f, 1f, 32);

    StdDraw.setCanvasSize(640, 640);
    StdDraw.setScale(-1.2, 1.2);

    // NUM_PTS points on a circle at (0,0) and radius = 1;
    Point2D.Double[] points = new Point2D.Double[NUM_PTS];
    double angleStep = 2*Math.PI/NUM_PTS;
    for (int i = 0; i < NUM_PTS; i++)
      points[i] = new Point2D.Double( Math.cos(angleStep * i),
                                      Math.sin(angleStep * i));

    StdDraw.enableDoubleBuffering();
          // necessary due to drawing complexity
    double mult = 1;
    while (true) {
      drawCircle(points, mult);
      mult += 0.01;
      StdDraw.pause(200);  // animation rate
    }
  }  // end of main()



  private static void drawCircle(
                  Point2D.Double[] points, double mult) 
  {
    // clear region inside circle
    StdDraw.setPenColor(Color.WHITE);
    StdDraw.filledCircle(0,0,1);

    // update mult string
    StdDraw.setPenColor(Color.WHITE);
    StdDraw.filledRectangle(-1.1, 1.1, 0.25, 0.25);
    StdDraw.setPenColor(Color.BLACK);
    StdDraw.text(-1.1, 1.1, String.format("%.2f", mult));

    // draw a circle of points 
    StdDraw.setPenRadius(0.01);
    for (int i = 0; i < points.length; i++)
      StdDraw.point(points[i].x, points[i].y);

    // draw lines between the points
    StdDraw.setPenRadius();   // default line width
    StdDraw.setPenColor(colors[colCount]);
    colCount = (colCount+1) % colors.length;
            // modulo here ^^^
    for (int i = 0; i < points.length; i++) {
       int dest = ((int)Math.round(i*mult))%points.length;
                           // modulo here ^^^
       StdDraw.line(points[i].x, points[i].y, 
                    points[dest].x, points[dest].y);
    }    

    StdDraw.show();   // draw to screen now
  }  // end of drawCircle()



  public static Color[] generateRainbow(float saturation, float brightness, int size)
  /* Generate a rainbow color table (HSV ramp) with
     saturation factor (from 0 to 1),
     brightness factor (from 0 to 1), and
     the size of the table.
  */
  {
    Color[] table = new Color[size];
    for (int i = 0; i < table.length; i++)
      table[i] = Color.getHSBColor(((float)i)/((float)size), 
                                         saturation, brightness);
    return table;
  } // end of generateRainbow()


}  // end of DrawCircle class