
// FordCircles.java
// Andrew Davison, ad@coe.psu.ac.th, April 2023

/* Display a Farey sequence as a series of Ford circles.

   For each p/q in the sequence there is a Ford circle 
   whose center is at (p/q , 1/(2q^2)) and whose 
   radius is 1/(2q^2)

   No matter how many p's and q's are picked, none of 
   the Ford circles intersect (and all are tangent to the x-axis).
   
   https://en.wikipedia.org/wiki/Farey_sequence
   https://en.wikipedia.org/wiki/Ford_circle

   Usage:
     > compile FordCircles.java
     > run FordCircles <n>
   e.g.
     > run FordCircles 9
        // a version of this appears on the Ford circle wiki page
     > run FordCircles 30

   The Farey sequence is generated by the FareySeq object
   using a default range of [0, 1]. The n argument is the
   maximum denominator used in the generated sequence.

   Other Farey examples can be found in:
     FareySeq.java, FareyGrid.java
*/

import java.math.*;
import java.util.*;

import org.apache.commons.numbers.fraction.*;
import org.apache.commons.numbers.core.*;


public class FordCircles
{

  public static void main(String[] args)
  {
    if (args.length != 1) {
      System.out.println("Usage: run FordCircles <n>");
      return;
    }
    int n = Math.abs(Nut.parseInt(args[0]));

    FareySeq fs = new FareySeq(n); 
    ArrayList<Fraction> fseq = fs.getFareySeq();
    System.out.println("Farey Sequence; den=" + n + "; [0 - 1]:");
    System.out.println(fseq + "\n");

    StdDraw.setCanvasSize(800, 800);
    StdDraw.setScale(0, 1);

    /* For every fraction p/q in the sequence there is a 
       Ford circle with radius 1/(2q^2) and centre at (p/q, 1/(2q^2)).
    */
    for(Fraction f : fseq) {
      int q = f.getDenominator();
      double xc = f.doubleValue();    // double version of p/q
      double yc = 1.0/(2.0*q*q); 
      StdDraw.circle(xc, yc, yc);   // yc also used as radius
    }
  } /* main */

}  // end of FordCircles class
