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

public class PathIteratedCircle extends JPanel  {
    public PathIteratedCircle() {
        setBackground(Color.white);
    }    
    int pointSize = 2;
    int pointSize2 = 2*pointSize;
    
    public void paintComponent(Graphics gfx) {
        super.paintComponent(gfx);
        Graphics2D g = (Graphics2D) gfx;
	g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			   RenderingHints.VALUE_ANTIALIAS_ON);

	Ellipse2D.Double circle = new Ellipse2D.Double(50, 50, 200, 200);
	PathIterator iterator = circle.getPathIterator(null);
	double lastX=0, lastY=0, beginX=0, beginY=0;
	while(!iterator.isDone()) {
	    float[] coords = new float[6];
	    int type = iterator.currentSegment(coords);
	    switch(type) {
	    case(PathIterator.SEG_MOVETO): {
		beginX = coords[0];  beginY = coords[1];
		lastX  = coords[0];  lastY  = coords[1];
		break;
	    }
	    case(PathIterator.SEG_LINETO): {
		Line2D.Double line = new Line2D.Double(lastX, lastY,
						       coords[0], coords[1]);
		g.setPaint(Color.red);
		g.draw(line);
		drawPoint(lastX, lastY, g);
		lastX = coords[0];  lastY = coords[1];
		break;
	    }
	    case(PathIterator.SEG_QUADTO): {
		QuadCurve2D.Double quad = 
		    new QuadCurve2D.Double(lastX, lastY,
					   coords[0], coords[1],
					   coords[2], coords[3]);
		g.setPaint(Color.green);
		g.draw(quad);
		drawLine(lastX, lastY, coords[0], coords[1], g);
		drawLine(coords[0], coords[1], coords[2], coords[3], g);
		drawPoint(lastX, lastY, g);
		drawPoint(coords[0], coords[1], g);
		lastX = coords[2];  lastY = coords[3];
		break;
	    }
	    case(PathIterator.SEG_CUBICTO): {
		CubicCurve2D.Double cubic = 
		    new CubicCurve2D.Double(lastX, lastY,
					    coords[0], coords[1],
					    coords[2], coords[3],
					    coords[4], coords[5]);
		g.setPaint(Color.blue);
		g.draw(cubic);
		drawLine(lastX, lastY, coords[0], coords[1], g);
		drawLine(coords[2], coords[3], coords[4], coords[5], g);
		drawPoint(lastX, lastY, g);
		drawPoint(coords[0], coords[1], g);
		drawPoint(coords[2], coords[3], g);
		lastX = coords[4];  lastY = coords[5];
		break;
	    }
	    case(PathIterator.SEG_CLOSE): {
		g.setPaint(Color.magenta);
		g.draw(new Line2D.Double(lastX, lastY, beginX, beginY));
		drawPoint(lastX, lastY, g);
		drawPoint(beginX, beginY, g);
		break;
	    }
	    }
	    iterator.next();
	}
    }

    public void drawLine(double x0, double y0, 
			 double x1, double y1, Graphics2D g) {
	Line2D.Double line = new Line2D.Double(x0, y0, x1, y1);
	g.setPaint(Color.lightGray);
	g.draw(line);
    }

    public void drawPoint(double x, double y, Graphics2D g) {
	double r = 2;
	Rectangle2D.Double point = new Rectangle2D.Double(x-r, y-r, 2*r, 2*r);
	g.setPaint(Color.red);
	g.fill(point);
	g.setPaint(Color.black);
	g.draw(point);
    }

    public static void main(String[] args) {
        JPEGDrawFrame frame = new JPEGDrawFrame("PathIteratedCircle");
        PathIteratedCircle circle = new PathIteratedCircle();
        frame.getContentPane().add(circle, BorderLayout.CENTER);
        circle.setPreferredSize(new Dimension(300, 300));
        frame.pack();
        frame.show();
    }
}
