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

public class HexagonalTiling extends JPanel  {
    double side;
    public HexagonalTiling(double s) {
	side = s;
        setBackground(Color.white);
    }    
    
    public void paintComponent(Graphics gfx) {
        super.paintComponent(gfx);
        Graphics2D g = (Graphics2D) gfx;
	g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			   RenderingHints.VALUE_ANTIALIAS_ON);

	GeneralPath hexagon = new GeneralPath();
	hexagon.moveTo(1, 0);
	for (int i = 1; i < 6; i++) 
	    hexagon.lineTo((float)Math.cos(i*Math.PI/3), 
			   (float)Math.sin(i*Math.PI/3));
	hexagon.closePath();
	AffineTransform toTile = new AffineTransform();
	toTile.rotate(Math.PI/6);
	toTile.scale(side, side);
	Shape hexShape = toTile.createTransformedShape(hexagon);

	g.setPaint(new Color(0.5f, 0.5f, 1f));
	g.setStroke(new BasicStroke(2f));

	Rectangle rect = getBounds();
	int maxX = (int) (rect.width/side);
	int maxY = (int) (rect.height/side);
	double distanceBetweenCenters = side*Math.sqrt(3);
	AffineTransform left = new AffineTransform();
	for (int i = 0; i < maxX; i++) {
	    AffineTransform toRight = new AffineTransform(left);
	    for (int j = 0; j < maxY; j++) {
		g.draw(toRight.createTransformedShape(hexShape));
		toRight.translate(distanceBetweenCenters, 0);
	    }
	    left.rotate(2*Math.PI/3);
	    left.translate(distanceBetweenCenters, 0);
	    left.rotate(-2*Math.PI/3);
	}
	
	
    }

    public static void main(String[] args) {
	double side = 20;
	try {
	    side = Double.parseDouble(args[0]);
	} catch(Exception ex) { }
	HexagonalTiling tiling = new HexagonalTiling(side);

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