import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

public class MovingEuclidI extends JPanel implements MouseListener,
MouseMotionListener {
    MoveablePoint[] p;
    MoveablePoint moving = null;
    public MovingEuclidI() {
	p = new MoveablePoint[2];
	p[0] = new MoveablePoint(100, 100);
	p[1] = new MoveablePoint(150, 150);
        setBackground(Color.white);
	addMouseListener(this);
	addMouseMotionListener(this);
    } 

    public void mouseClicked(MouseEvent me) { }
    public void mouseEntered(MouseEvent me) { }
    public void mouseExited(MouseEvent me) { }
    public void mouseMoved(MouseEvent me) { }

    public void mousePressed(MouseEvent me) {
	for (int i = 0; i < 2; i++) {
	    if (p[i].hit(me.getX(), me.getY())) {
		moving = p[i];  
		movePoint(me.getX(), me.getY());
		return;
	    }
	}
    }
    public void mouseReleased(MouseEvent me) {
	movePoint(me.getX(), me.getY());
	moving = null;
    }

    public void mouseDragged(MouseEvent me) {
	movePoint(me.getX(), me.getY());
    }    

    public void movePoint(int x, int y) {
	if (moving == null) return;
	moving.setLocation(x, y);
	repaint();
    }

    public void paintComponent(Graphics gfx) {
	// usual stuff
        super.paintComponent(gfx);
        Graphics2D g = (Graphics2D) gfx;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);

	// set up circles
        double r = p[0].distance(p[1]);
        Ellipse2D.Double circle1 =
            new Ellipse2D.Double(p[0].x - r, p[0].y - r, 2*r, 2*r);
        Ellipse2D.Double circle2 =
            new Ellipse2D.Double(p[1].x - r, p[1].y - r, 2*r, 2*r);

	// find the third point
	AffineTransform at = new AffineTransform();
	at.translate(p[0].x, p[0].y);
	at.rotate(Math.PI/3);
	at.translate(-p[0].x, -p[0].y);
	Point2D.Double p2 = (Point2D.Double) at.transform(p[1], null);

	/* Here is another way you could do it with coordinates

        double u = p2.x - p[1].x;  double v = p2.y - p[1].y;
        double c = Math.cos(Math.PI/3);  double s = Math.sin(Math.PI/3);
        double ix = c * u - s * v + p[1].x;  double iy = s * u + c * v + p[1].y;
        Point2D.Double p2 = new Point2D.Double(ix, iy);
	*/ 

	// set up triangle
	GeneralPath path = new GeneralPath();
	path.moveTo((float) p[0].x, (float) p[0].y);
	path.lineTo((float) p[1].x, (float) p[1].y);
	path.lineTo((float) p2.x, (float) p2.y);
	path.closePath();

	// draw circles and triangle
        g.draw(circle1);  g.draw(circle2);        g.draw(path);

	// add points
        double size = 2;
        Ellipse2D.Double[] points = new Ellipse2D.Double[3];
        points[0] = getDot(p[0]);   points[1] = getDot(p[1]);
        points[2] = getDot(p2);

        g.setPaint(new Color(1f, 0.2f, 0.2f));
        g.fill(points[0]);  g.fill(points[1]);
        g.setPaint(new Color(0.2f, 0.2f, 1f));
        g.fill(points[2]);

        g.setPaint(Color.black);
        for (int i = 0; i < 3;  i++) g.draw(points[i]);

	// add labels
	g.setFont(new Font("sanserif", Font.BOLD, 12));
	g.drawString("A", (float)p[0].x + 3, (float) p[0].y - 3);
	g.drawString("B", (float)p[1].x + 3, (float) p[1].y - 3);
	g.drawString("C", (float)p2.x + 3, (float) p2.y - 3);
    }

    

    public Ellipse2D.Double getDot(Point2D.Double p) {
        double size = 3;
        return new Ellipse2D.Double(p.x - size, p.y - size,
                                    2*size, 2*size);
    }

    public static void main(String[] args) {
        MovingEuclidI euclid = new MovingEuclidI();
        euclid.setPreferredSize(new Dimension(300, 300));
        JFrame frame = new JFrame("MovingEuclidI");
	frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(euclid);
        frame.pack();
        frame.setVisible(true);
    }
        
}
        
                                         
