package graphics.draw2d;


import java.awt.*;

class Circle2d extends Shape
    implements Intersects {
  int x1 = 0;
  int y1 = 0;
  int diameter = 1;
  int radius = 1;
  Vec2d center = new Vec2d(0, 0);
  double radiusSq;

  Circle2d(int _x1, int _y1, int _diameter) {
    x1 = _x1;
    y1 = _y1;
    diameter = _diameter;
    radius = diameter / 2;
    radiusSq = radius * radius;
  }

  Circle2d(int _x1, int _y1, int _x2, int _y2) {
    x1 = _x1;
    y1 = _y1;
    int dx = x1 - _x2;
    int dy = y1 - _y2;
    diameter = (int) Math.sqrt(dx * dx + dy * dy);
    if (_x1 > _x2) x1 = _x2;
    if (_y1 > _y2) y1 = _y2;
    radius = diameter / 2;
    radiusSq = radius * radius;
    center.v[0] = x1 + radius;
    center.v[1] = y1 + radius;
  }

  public void paint(Graphics g) {
    int xc = (int) center.v[0];
    int yc = (int) center.v[1];
    g.drawOval(x1, y1, diameter, diameter);
    g.fillOval(xc, yc, 2, 2);
    g.drawString("(" + xc + "," + yc + ")", xc + 3, yc + 3);
    g.drawLine(xc, yc, xc - radius, yc);
  }

  public String toString() {
    return
        "xc,yc,r=" + center.v[0] + "," + center.v[1] + "," + radius;
  }


  public boolean inside(Vec2d p) {

    Vec2d n = new Vec2d(p);
    n.sub(center);
    if (n.dot(n) > radiusSq)
      return false;
    else
      return true;
  }

  public Vec2d intersect(Ray2d ray) {

    double t,          /* where the ray intersects */
        // vDotV = distance square from sphere center to
        // ray origin
        vDotV,
        dDotV,
        thc;        /* length sqare of the half chord */

    // vector to the center of the sphere from
    // ray origin
    Vec2d v
        = new Vec2d(center.v[0], center.v[1]);
    boolean inside = false;
    //System.out.println(ray);

    /* use the closest approach algorithm */
    // v = v - ray.p
    //System.out.println(v);
    v.sub(ray.p);
    // loc = v^2
    vDotV = v.dot(v);
    // Are we inside the circle?
    if (vDotV <= radiusSq)
      inside = true;

    // dDotV = D dot V =
    // cos(angle between ray and vec to center);
    dDotV = v.dot(ray.d);   /* find the closest approach */

    // object is behind the ray origin
    if ((inside != true) && (dDotV <= 0.0))
      return null;

    /* compute the half chord square from the ray intersection to the
       intersection normal. */
    thc = (dDotV * dDotV) - vDotV + radiusSq;
    if (thc < 0.0)
      return null;   /* ray misses the sphere */

    /* find the ray intersection */
    if (inside == true)
      t = dDotV + Math.sqrt(thc);
    else
      t = dDotV - Math.sqrt(thc);

    return ray.vecOnLine((double) t);
  }
}