/**
* @license:
* The MIT License (MIT)
*
* Copyright (c) 2016 David Okusanya
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*
*
* @brief: Drawing a sequence of hexagons
*
*/
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
class HexagonGrid extends Frame{
private int margin;
HexagonGrid(int margin){
super("HexagonGrid - Flat Orientation");
this.margin = margin;
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
setSize(400, 400);
HexagonRect hexa = new HexagonRect(margin);
add("Center", hexa);
show();
}
class HexagonRect extends Canvas{
private int margin, mousePointX, mousePointY, height;
private int vertex0X, vertex0Y, temp_vertex0Y,
vertex1X, vertex1Y, temp_vertex1Y,
vertex2X, vertex2Y, temp_vertex2Y,
vertex3X, vertex3Y, temp_vertex3Y,
vertex4X, vertex4Y, temp_vertex4Y,
vertex5X, vertex5Y, temp_vertex5Y;
/**
* This is the rectangle that would contain the grid
*/
HexagonRect(int margin){
this.margin = margin;
addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent mt){
mousePointX = mt.getX();
mousePointY = mt.getY();
repaint(); // To facilitate a redrawing of the points
}
});
}
/**
* Return the radius of the hexagon from the point of the mouse click
* @return radius An integer value
*/
public int getRadius(){
if (mousePointX <= margin){
mousePointX += margin;
}
if (mousePointY <= margin){
mousePointY += margin;
}
int radiusX = mousePointX - margin;
int radiusY = mousePointY - margin;
int radius = (int) Math.sqrt((double)(radiusX * radiusX + radiusY * radiusY));
return radius;
}
/**
* Calculate all the vertices of the first pentagon in the grid
* @param radius An integer value
* @param height An integer value
*/
public void computeVertices(int radius, int height){
// Going clockwise
// Left Topmost vertex
vertex0X = (mousePointX - radius / 2);
vertex0Y = (mousePointY - height / 2);
// Right Topmost vertex
vertex1X = (mousePointX + radius / 2);
vertex1Y = (mousePointY - height / 2);
// Rightmost vertex
vertex2X = (mousePointX + radius);
vertex2Y = mousePointY;
// Right Bottom vertex
vertex3X = (mousePointX + radius / 2);
vertex3Y = (mousePointY + height / 2);
// Left Bottom vertex
vertex4X = (mousePointX - radius / 2);
vertex4Y = (mousePointY + height / 2);
// Leftmost vertex
vertex5X = (mousePointX - radius);
vertex5Y = mousePointY;
}
/**
* This resets the y-coordinates of the hexagon column
*/
public void resetTempVertices(){
temp_vertex5Y = vertex5Y;
temp_vertex0Y = vertex0Y;
temp_vertex4Y = vertex4Y;
temp_vertex1Y = vertex1Y;
temp_vertex3Y = vertex3Y;
temp_vertex2Y = vertex2Y;
}
/**
* This increments all the x-coordinates, to enable another columns to drawn alongside the already
* drawn column
* @param radius An integer value
*/
public void incrementX(int radius){
vertex5X += 3 * radius;
vertex0X += 3 * radius;
vertex4X += 3 * radius;
vertex1X += 3 * radius;
vertex3X += 3 * radius;
vertex2X += 3 * radius;
}
/**
* Drawing method
* @param g Graphics object
*/
public void paint(Graphics g){
int radius = getRadius();
System.out.println("Radius = " + radius);
if (radius > 0){
height = Math.round(((float)(Math.sqrt(3) *radius)));
System.out.println("Height = " + height);
int nVert = numOfVerticalHexagons(radius);
int nHort = numOfHorizontalHexagons(radius);
computeVertices(radius, height);
for (int j = 0; j < nHort; j++){
resetTempVertices();
for (int i = 0; i < nVert; i++){
// Draw northwest line
g.drawLine(vertex0X, temp_vertex0Y, vertex5X, temp_vertex5Y);
// Draw southwest line
g.drawLine(vertex5X, temp_vertex5Y, vertex4X, temp_vertex4Y);
// Draw top line
g.drawLine(vertex0X, temp_vertex0Y, vertex1X, temp_vertex1Y);
// Draw northeast line
g.drawLine(vertex1X, temp_vertex1Y, vertex2X, temp_vertex2Y);
if (j != nHort - 1){ // remove the last drawn line
// Draw top of the next column
g.drawLine(vertex2X, temp_vertex2Y, vertex2X + radius, temp_vertex2Y);
}
// Draw southeast line
g.drawLine(vertex2X, temp_vertex2Y, vertex3X, temp_vertex3Y);
temp_vertex5Y += height;
temp_vertex0Y += height;
temp_vertex4Y += height;
temp_vertex1Y += height;
temp_vertex3Y += height;
temp_vertex2Y += height;
}
// Draw the last line(botton line) joining the bottom hexagons
g.drawLine(vertex0X, temp_vertex0Y, vertex1X, temp_vertex1Y);
incrementX(radius);
}
}
}
/**
* Returns the number of hexagons that can be fit in one column along the rectangle's height
* @param radius An integer value
* @return count An integer value
*/
public int numOfVerticalHexagons(int radius){
Dimension d = getSize();
int maxHeight = d.height - 1;
return maxHeight / (2 * radius);
}
/**
* Returns the number of hexagons that can be fit in one row along the rectangle's width
* @param radius An integer value
* @return count An integer value
*/
public int numOfHorizontalHexagons(int radius){
// Two columns of hexagons make one unit
// Width of one hexagon = 2 x radius
// There is an overlap of (1/2) * radius between the two columns
Dimension d = getSize();
int maxWidth = d.width - 1;
if (maxWidth % 7 == 0){
return maxWidth / ((7 / 2) * radius);
}
else {
return (maxWidth - 1) / ((7 / 2) * radius);
}
}
}
public static void main(String[] args){
// Usage : java HexagonGrid
new HexagonGrid(40); // Static value(change if desired)
}
}