package graphics.carl;

/*-----------------------------
class graphics.carl.PointArray.java

October 5, 2001, Carl Weiman

Index Conventions:
------------------
Ring (or column) index first  (as x-axis)
Ray (or row)     index second (as y-axis)


************************************/

// package mosaics


public class PointArray {

  //----------------------
  //    Instance variables |
  //----------------------
  private java.awt.geom.Point2D.Float pts[][];  //2D array of points accessible via getter
  // where order is: pts[rings][rays]
  private float radii[];            // Array of circlet radii, per ring
  private java.awt.geom.Point2D.Float origin;   // Coordinate system origin
  private float innerRadius;        // radius of inner circle of points
  private int ringCount, rayCount;// number of rings, rays
  private float expansion;      // Scale factor of expansion per ring

  // ------------------
  //    Constructors    |
  // ------------------

  //-----------------------
  //    General constructor
  public PointArray(int _rings, int _rays, java.awt.geom.Point2D.Float _origin, float _radius) {
    float x, y; // Computation coordinates
    ringCount = _rings;
    rayCount = _rays;
    origin = _origin;
    innerRadius = _radius;

    pts = new java.awt.geom.Point2D.Float[ringCount][rayCount];
    radii = new float[ringCount];


    float f_PIrays = (float) Math.PI / (float) rayCount;    // (2*PI/rayCount)
    float f_2PIrays = 2f * f_PIrays;

    expansion = (float) Math.exp(f_2PIrays);                    // exp(above)

    radii[0] = (float) (innerRadius * Math.sin(f_PIrays));
    for (int i_ring = 1; i_ring < ringCount; i_ring++) {
      radii[i_ring] = radii[i_ring - 1] * expansion;
    }


    //----------------------------------------------------
    // Populate a ray at a time, rings outward on each ray
    for (int i_ray = 0; i_ray < rayCount; i_ray++) {
      processRay(i_ray, f_2PIrays);

    } // End of ray for-loop

  } // End of general constructor

  private void processRay(int i_ray, float f_2PIrays) {
    float x;
    float y;
    x = innerRadius * (float) Math.cos(i_ray * f_2PIrays);
    y = -1 * innerRadius * (float) Math.sin(i_ray * f_2PIrays);//Cartesian y coord
    pts[0][i_ray] = new java.awt.geom.Point2D.Float(x + origin.x, y + origin.y);
    // Construct magnified images of each so-found to populate rings:
    processRing(x, y, i_ray);
  }

  private void processRing(float x, float y, int i_ray) {
    for (int i = 1; i < ringCount; i++) {
      x *= expansion;
      y *= expansion;
      pts[i][i_ray] = new java.awt.geom.Point2D.Float(x + origin.x, y + origin.y);
    } // End of ring for-loop
  }

  //----------------------------------------
  //    Default constructor takes no arguments
  //        16 ringCount, 48 rayCount
  //        origin (100f,100f), innerRadius 100f
  public PointArray() {
    this(16, 48, new java.awt.geom.Point2D.Float(100f, 100f), 10f);
  }

  // --------------------------------------
  //  Getters (No setters, use general constructor)
  //---------------------------------------

  public java.awt.geom.Point2D.Float[][] get_points() {
    return pts;
  }

  public int get_rayCount() {
    return rayCount;
  }

  public int get_ringCount() {
    return ringCount;
  }

  public float get_innerRadius() {
    return innerRadius;
  }

  public java.awt.geom.Point2D.Float get_origin() {
    return origin;
  }

  public float get_expansion() {
    return expansion;
  }

  public String points_toString() {
    String str = "";
    for (int i_ring = 0; i_ring < ringCount; i_ring++) {
      for (int i_ray = 0; i_ring < ringCount; i_ring++) {
        str += "\n  r = " + radii[i_ring] + pts[i_ring][i_ray];
      }
    }
    return (str);
  }

  public String toString() {
    String str;
    str = "\n rays: " + rayCount + "; rings: " + ringCount;
    str += "\n radius: " + innerRadius;
    str += "\n origin: " + origin.toString();
    str += "\n expansion: " + expansion;
    return str;
  }

  //--------------------------------------
  // main method for testing purposes only
  //--------------------------------------
  public static void main(String args[]) {
    PointArray lppa = new PointArray(3, 4, new java.awt.geom.Point2D.Float(100f, 100f), 100f);
    System.out.println(lppa.points_toString());
    System.out.println(lppa.toString());
  } // End of main

  public java.awt.geom.Point2D.Float[][] getPts() {
    return pts;
  }

  public void setPts(java.awt.geom.Point2D.Float[][] pts) {
    this.pts = pts;
  }

  public float[] getRadii() {
    return radii;
  }

  public void setRadii(float[] radii) {
    this.radii = radii;
  }

  public java.awt.geom.Point2D.Float getOrigin() {
    return origin;
  }

  public void setOrigin(java.awt.geom.Point2D.Float origin) {
    this.origin = origin;
  }

  public float getInnerRadius() {
    return innerRadius;
  }

  public void setInnerRadius(float innerRadius) {
    this.innerRadius = innerRadius;
  }

  public int getRingCount() {
    return ringCount;
  }

  public void setRingCount(int ringCount) {
    this.ringCount = ringCount;
  }

  public int getRayCount() {
    return rayCount;
  }

  public void setRayCount(int rayCount) {
    this.rayCount = rayCount;
  }

  public float getExpansion() {
    return expansion;
  }

  public void setExpansion(float expansion) {
    this.expansion = expansion;
  }

}