// dodecahedron.java   a very basic, yet complete java frame application

import java.awt.*;
import java.awt.event.*;

public class dodecahedron extends Frame
{
  int xpoints[] = new int[5];
  int ypoints[] = new int[5];
  int npoints = 5;
  double xc = 350.0;
  double yc = 350.0;
  double r = 85.0;
  double a72 = Math.PI*72.0/180.0;
  boolean fill = true;
 
  dodecahedron()
  {
    setTitle("dodecahedron");
    setSize(800,800);
    setBackground(Color.white);
    setForeground(Color.black);
    addWindowListener(new WindowAdapter()
    {
      public void windowClosing(WindowEvent e)
      {
        System.exit(0);
      }
    });
    setVisible(true);
    this.addMouseListener (new mousePressHandler());
  } // end constructor


  class mousePressHandler extends MouseAdapter
  {
    public void mousePressed (MouseEvent e)
    {
      requestFocus();
      // System.out.println("press"); // debug print
      fill = !fill;
      repaint();
      System.exit(0);
    }
  } // end mousePressHandler

  public void paint(Graphics g)
  {
    double x0, y0, x1, y1, x2, y2, x3, y3, x4, y4 ;
    double xcv, ycv, ar, dr, xct, yct, arr, drr;

    g.drawString("dodecahedron", 50, 50);
    get_points(0.0, xc, yc);
    g.setColor(Color.blue);
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    x0 = xc+r;
    y0 = yc;
    x1 = xc + r*Math.cos(a72);
    y1 = yc + r*Math.sin(a72);
    dr = dist(xc, yc, x0, y0, x1, y1);
    ar = a72/2.0;
    xcv = xc + 2.0*dr*Math.cos(ar);
    ycv = yc + 2.0*dr*Math.sin(ar);
    get_points(ar, xcv, ycv);
    g.setColor(Color.red);
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    ar = 3.0*a72/2.0;
    xcv = xc + 2.0*dr*Math.cos(ar);
    ycv = yc + 2.0*dr*Math.sin(ar);
    get_points(ar, xcv, ycv);
    g.setColor(Color.green);
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    ar = 5.0*a72/2.0;
    xcv = xc + 2.0*dr*Math.cos(ar);
    ycv = yc + 2.0*dr*Math.sin(ar);
    get_points(ar, xcv, ycv);
    g.setColor(Color.pink);
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    ar = 7.0*a72/2.0;
    xcv = xc + 2.0*dr*Math.cos(ar);
    ycv = yc + 2.0*dr*Math.sin(ar);
    get_points(ar, xcv, ycv);
    g.setColor(Color.yellow);
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    ar = 9.0*a72/2.0;
    xcv = xc + 2.0*dr*Math.cos(ar);
    ycv = yc + 2.0*dr*Math.sin(ar);
    get_points(ar, xcv, ycv);
    g.setColor(Color.magenta);
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    ar = a72/2.0;
    xcv = xc + 2.0*dr*Math.cos(ar);
    ycv = yc + 2.0*dr*Math.sin(ar);
    ar = 0.0;
    xcv = xcv + 2.0*dr;
    ycv = ycv + 0.0;
    drr = Math.sqrt((xcv-xc)*(xcv-xc)+(ycv-yc)*(ycv-yc));
    arr = Math.atan2(ycv-yc,xcv-xc);
    get_points(ar, xcv, ycv);
    g.setColor(Color.gray);
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    xcv = xc + drr*Math.cos(arr+a72);
    ycv = yc + drr*Math.sin(arr+a72);
    get_points(ar, xcv, ycv);
    g.setColor(new Color(95, 195, 255));
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    xcv = xc + drr*Math.cos(arr+2.0*a72);
    ycv = yc + drr*Math.sin(arr+2.0*a72);
    get_points(ar, xcv, ycv);
    g.setColor(Color.cyan);
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    xcv = xc + drr*Math.cos(arr+3.0*a72);
    ycv = yc + drr*Math.sin(arr+3.0*a72);
    get_points(ar, xcv, ycv);
    g.setColor(new Color(151,0,151));
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    xcv = xc + drr*Math.cos(arr+4.0*a72);
    ycv = yc + drr*Math.sin(arr+4.0*a72);
    get_points(ar, xcv, ycv);
    g.setColor(new Color(0, 151, 0));
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

    ar = a72/2.0;
    xcv = xc + drr*Math.cos(arr) + 2.0*dr*Math.cos(ar);
    ycv = yc + drr*Math.sin(arr) + 2.0*dr*Math.sin(ar);
    get_points(ar, xcv, ycv);
    g.setColor(new Color(151,151,0));
    if(fill) g.fillPolygon(xpoints, ypoints, npoints);
    else     g.drawPolygon(xpoints, ypoints, npoints);

  } // end paint

  void get_points(double ar, double xcv, double ycv)
  {
    xpoints[0] = (int)(xcv+r*Math.cos(ar));
    ypoints[0] = (int)(ycv+r*Math.sin(ar));
    xpoints[1] = (int)(xcv + r*Math.cos(a72+ar));
    ypoints[1] = (int)(ycv + r*Math.sin(a72+ar));
    xpoints[2] = (int)(xcv + r*Math.cos(2.0*a72+ar));
    ypoints[2] = (int)(ycv + r*Math.sin(2.0*a72+ar));
    xpoints[3] = (int)(xcv + r*Math.cos(3.0*a72+ar));
    ypoints[3] = (int)(ycv + r*Math.sin(3.0*a72+ar));
    xpoints[4] = (int)(xcv + r*Math.cos(4.0*a72+ar));
    ypoints[4] = (int)(ycv + r*Math.sin(4.0*a72+ar));
  } // end get_points

  double dist(double a1x, double a1y, // point
              double a2x, double a2y, // line
              double a3x, double a3y)
  {
    /* distance from a point to a line segment */
    double d, d1, d2, d3, a1, b1, c1, a2, b2, c2;
    double x, y;
    int out = 0;
  
    a1 = a3y-a2y;
    b1 = a2x-a3x;
    c1 = a2y*(a3x-a2x)-a2x*(a3y-a2y);
    a2 = a2x-a3x;
    b2 = a2y-a3y;
    c2 = a1y*(a3y-a2y)-a1x*(a2x-a3x);
    if(a2x==a3x) x = a2x;
    else
    {
      x = (b1*c2-b2*c1)/(b2*a1-b1*a2);
      if(x>a2x && x>a3x) out = 1;
      if(x<a2x && x<a3x) out = 1;
    }
    if(a2y==a3y) y = a2y;
    else
    {
      y = (a1*c2-a2*c1)/(a2*b1-a1*b2);
      if(y>a2y && y>a3y) out = 1;
      if(y<a2y && y<a3y) out = 1;
    }
    d1 = Math.sqrt((a1x-x)*(a1x-x)+(a1y-y)*(a1y-y));
    d2 = Math.sqrt((a2x-a1x)*(a2x-a1x)+(a2y-a1y)*(a2y-a1y));
    d3 = Math.sqrt((a3x-a1x)*(a3x-a1x)+(a3y-a1y)*(a3y-a1y));
    if(out==0)     d = d1;
    else if(d2<d3) d = d2;
    else           d = d3;
    return d;
  } /* end dist */

  public static void main(String args[])
  {
    new dodecahedron();
  } // end main
} // end class dodecahedron

