import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

public class TriangleInscribed extends JPanel  {
    Point2D.Double[] points;
    int pointSize = 4;
    int pointSize2 = 2*pointSize;

    public TriangleInscribed(Point2D.Double[] p) {
	points = p;
        setBackground(Color.white);
    }    
    
    public void paintComponent(Graphics gfx) {
        super.paintComponent(gfx);
        Graphics2D g = (Graphics2D) gfx;
	g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			   RenderingHints.VALUE_ANTIALIAS_ON);

	// find the angles made by the vectors from one point to the other
	double[][] angle = new double[3][2];
	Color angleColor = new Color(0.8f, 0.5f, 0.5f);
	for (int i = 0; i < 3; i++) {
	    Point2D.Double base = points[i];
	    for (int j = 0; j < 2; j++) {
		Point2D.Double other = points[(i+j+1) % 3];
		angle[i][j] = Math.atan2(other.y - base.y,
					 other.x - base.x);
	    }
	}

	// find the angle bisectors, then the intersection of the bisectors
	double alpha0 = (angle[0][0] + angle[0][1])/2;
	double alpha1 = (angle[1][0] + angle[1][1])/2;
	double u0x = Math.cos(alpha0);  double u0y = Math.sin(alpha0);
	double u1x = Math.cos(alpha1);  double u1y = Math.sin(alpha1);
	double v1x = -u1y;  double v1y = u1x;
	double t = ((points[1].x - points[0].x)*v1x +
		    (points[1].y - points[0].y)*v1y) /
	    (u0x * v1x + u0y * v1y);
	Point2D.Double incenter = 
	    new Point2D.Double(points[0].x + t*u0x, points[0].y + t*u0y);

	// draw angle bisectors to incenter
	g.setPaint(new Color(0.7f, 0.7f, 0.7f));
	for (int i = 0; i < 3; i++) 
	    g.draw(new Line2D.Double(points[i], incenter));

	// find radius
	double dx0 = points[1].x - points[0].x;
	double dy0 = points[1].y - points[0].y;
	double dx1 = incenter.x - points[0].x;
	double dy1 = incenter.y - points[0].y;
	double crossProduct = dx0*dy1 - dx1*dy0;
	double r = Math.abs(crossProduct / 
			    Math.sqrt(dx0*dx0+dy0*dy0));
	// define and draw circle
	Ellipse2D.Double incircle = 
	    new Ellipse2D.Double(incenter.x-r, incenter.y-r,
				 2*r, 2*r);
	g.setPaint(new Color(0.5f, 0.5f, 0.8f));
	g.draw(incircle);

	// add angle markers
	// remember Arcs are defined in degrees
	for (int i = 0; i < 3; i++) {
	    Point2D.Double base = points[i];
	    double angleStart = -Math.toDegrees(angle[i][0]);
	    double angleExtent = -Math.toDegrees(angle[i][1] - angle[i][0]);
	    if (angleExtent < -180) angleExtent += 360;
	    if (angleExtent > 180) angleExtent -= 360;
	    Arc2D.Double arc = 
		new Arc2D.Double(base.x - 20, base.y - 20, 40, 40,
				 angleStart, angleExtent/2, Arc2D.PIE);
	    g.setPaint(angleColor);
	    g.fill(arc);
	    g.setPaint(Color.black);
	    g.draw(arc);

	    angleStart = -Math.toDegrees(angle[i][1]);
	    arc = 
		new Arc2D.Double(base.x - 20, base.y - 20, 40, 40,
				 angleStart, -angleExtent/2, Arc2D.PIE);
	    g.setPaint(angleColor);
	    g.fill(arc);
	    g.setPaint(Color.black);
	    g.draw(arc);
	}

	// draw triangle
	g.setPaint(Color.black);
	GeneralPath path = new GeneralPath();
	path.moveTo((float) points[0].x, (float) points[0].y);
	path.lineTo((float) points[1].x, (float) points[1].y);
	path.lineTo((float) points[2].x, (float) points[2].y);
	path.closePath();
	g.draw(path);
    }

    public static void main(String[] args) {
	Point2D.Double[] points = new Point2D.Double[3];
	for (int i = 0; i < 3; i++) 
	    points[i] = new Point2D.Double(Double.parseDouble(args[2*i]),
					   Double.parseDouble(args[2*i+1]));

        TriangleInscribed inscribed = new TriangleInscribed(points);

        JFrame frame = new JFrame("TriangleInscribed");
	frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(inscribed, BorderLayout.CENTER);
        inscribed.setPreferredSize(new Dimension(300, 300));
        frame.pack();
        frame.setVisible(true);
    }
}
