如何渲染六角网格
How to Render a Hex Grid
我目前正在开发一款需要渲染六边形网格以便为游戏提供场所的游戏。我正在使用偏移坐标将十六进制网格存储在内存中。当我尝试渲染网格时,我得到如下结果,在六角形之间带有 space。我希望六边形完美对齐,以便所有必需的都位于完全相同的点,并且它们的线重叠并且六角形
之间没有 space
每个六角形内的坐标代表该六角形的偏移坐标。
我正在使用下图中显示的距离 (source) 来决定渲染每个六角形的位置。
我能找到的唯一解决听起来像这个问题的 StackExchange 问题是 here. It, however, only talks about a data structure to store the hexes in and not how to render them from said structure. I am attempting to render them as described here,但是,我得到了如上所示的错误结果。
这是我处理渲染的代码部分(应该很容易推断出各种自定义方法的作用,如果有任何混淆请告诉我):
@Override
public void paint(Graphics g){
int quarterHexSize = 32; //using non static final member variables because I want to make this dynamically determine the largest size of the hexagons that will fit on the screen later
int halfHexSize = quarterHexSize * 2;
int hexSize = halfHexSize * 2;
int cx, cy, renderX, renderY;
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
for(cx=0;cx<5;cx++){
for(cy=0;cy<5;cy++){
Hex hex = board.getHexAt(cx, cy);
if(hex != null){
renderX = cx * 2; //multiplying by 2 rather than using floats to represent half offset to simplify code and because IIRC integers are faster, I got the same error when using floats
renderY = cy * 2;
if(renderY % 4 != 0){
renderX++;
}
//converts the somewhat arbitrary units into the actual display size units using the values from the image in the question
renderX *= hexSize;
renderY *= quarterHexSize * 3f;
//the numbers are divided by 2 to make up for the offset
renderX /= 2;
renderY /= 2;
//64 is added to both dimensions to shift the grid inside the window
renderX += 64;
renderY += 64;
drawHex(new RenderPoint(renderX, renderY), halfHexSize, g);
g.drawString(cx + ", " + cy, renderX, renderY);
}
}
}
}
private void drawHex(RenderPoint center, int hexSize, Graphics g){
drawHexLine(center, hexSize, 0, 1, g);
drawHexLine(center, hexSize, 1, 2, g);
drawHexLine(center, hexSize, 2, 3, g);
drawHexLine(center, hexSize, 3, 4, g);
drawHexLine(center, hexSize, 4, 5, g);
drawHexLine(center, hexSize, 5, 0, g);
}
private void drawHexLine(RenderPoint center, int hexSize, int firstCornerNum, int secondCornerNum, Graphics g){
RenderPoint firstCornerNumHexPoint = getHexCorner(center, hexSize, firstCornerNum);
RenderPoint secondCornerNumHexPoint = getHexCorner(center, hexSize, secondCornerNum);
g.drawLine(
firstCornerNumHexPoint.getX(), firstCornerNumHexPoint.getY(),
secondCornerNumHexPoint.getX(), secondCornerNumHexPoint.getY()
);
//g.drawString(String.valueOf(firstCornerNum), firstCornerNumHexPoint.getX(), firstCornerNumHexPoint.getY());
}
private RenderPoint getHexCorner(RenderPoint center, int hexSize, int cornerNum){
return RenderPoint.doublesToInts( //simply rounds the provided doubles and creates a RenderPoint object with these new rounded values
center.getX() + hexSize * Math.sin(cornerNum * 60 * 0.0174533), //decimal number converts from degrees to radians
center.getY() + hexSize * Math.cos(cornerNum * 60 * 0.0174533)
);
}
我已经确定是什么错误了。当我假设我在问题中发布的图表完全解释了六边形的位置时,我错过了 webpage 中的一个特定细节。
我已将变量 renderX 更改为:
renderX *= Math.round(HALF_SQRT_THREE * hexSize);
HALF_SQRT_THREE
是我在变量中定义的常量,以避免每次渲染六边形时都重新计算它。它被定义为 Math.sqrt(3)/2.0
.
引用自webpage:
The width of a hexagon is width = sqrt(3)/2 * height. The horizontal distance between adjacent hexes is horiz = width.
我目前正在开发一款需要渲染六边形网格以便为游戏提供场所的游戏。我正在使用偏移坐标将十六进制网格存储在内存中。当我尝试渲染网格时,我得到如下结果,在六角形之间带有 space。我希望六边形完美对齐,以便所有必需的都位于完全相同的点,并且它们的线重叠并且六角形
之间没有 space每个六角形内的坐标代表该六角形的偏移坐标。
我正在使用下图中显示的距离 (source) 来决定渲染每个六角形的位置。
我能找到的唯一解决听起来像这个问题的 StackExchange 问题是 here. It, however, only talks about a data structure to store the hexes in and not how to render them from said structure. I am attempting to render them as described here,但是,我得到了如上所示的错误结果。
这是我处理渲染的代码部分(应该很容易推断出各种自定义方法的作用,如果有任何混淆请告诉我):
@Override
public void paint(Graphics g){
int quarterHexSize = 32; //using non static final member variables because I want to make this dynamically determine the largest size of the hexagons that will fit on the screen later
int halfHexSize = quarterHexSize * 2;
int hexSize = halfHexSize * 2;
int cx, cy, renderX, renderY;
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
for(cx=0;cx<5;cx++){
for(cy=0;cy<5;cy++){
Hex hex = board.getHexAt(cx, cy);
if(hex != null){
renderX = cx * 2; //multiplying by 2 rather than using floats to represent half offset to simplify code and because IIRC integers are faster, I got the same error when using floats
renderY = cy * 2;
if(renderY % 4 != 0){
renderX++;
}
//converts the somewhat arbitrary units into the actual display size units using the values from the image in the question
renderX *= hexSize;
renderY *= quarterHexSize * 3f;
//the numbers are divided by 2 to make up for the offset
renderX /= 2;
renderY /= 2;
//64 is added to both dimensions to shift the grid inside the window
renderX += 64;
renderY += 64;
drawHex(new RenderPoint(renderX, renderY), halfHexSize, g);
g.drawString(cx + ", " + cy, renderX, renderY);
}
}
}
}
private void drawHex(RenderPoint center, int hexSize, Graphics g){
drawHexLine(center, hexSize, 0, 1, g);
drawHexLine(center, hexSize, 1, 2, g);
drawHexLine(center, hexSize, 2, 3, g);
drawHexLine(center, hexSize, 3, 4, g);
drawHexLine(center, hexSize, 4, 5, g);
drawHexLine(center, hexSize, 5, 0, g);
}
private void drawHexLine(RenderPoint center, int hexSize, int firstCornerNum, int secondCornerNum, Graphics g){
RenderPoint firstCornerNumHexPoint = getHexCorner(center, hexSize, firstCornerNum);
RenderPoint secondCornerNumHexPoint = getHexCorner(center, hexSize, secondCornerNum);
g.drawLine(
firstCornerNumHexPoint.getX(), firstCornerNumHexPoint.getY(),
secondCornerNumHexPoint.getX(), secondCornerNumHexPoint.getY()
);
//g.drawString(String.valueOf(firstCornerNum), firstCornerNumHexPoint.getX(), firstCornerNumHexPoint.getY());
}
private RenderPoint getHexCorner(RenderPoint center, int hexSize, int cornerNum){
return RenderPoint.doublesToInts( //simply rounds the provided doubles and creates a RenderPoint object with these new rounded values
center.getX() + hexSize * Math.sin(cornerNum * 60 * 0.0174533), //decimal number converts from degrees to radians
center.getY() + hexSize * Math.cos(cornerNum * 60 * 0.0174533)
);
}
我已经确定是什么错误了。当我假设我在问题中发布的图表完全解释了六边形的位置时,我错过了 webpage 中的一个特定细节。
我已将变量 renderX 更改为:
renderX *= Math.round(HALF_SQRT_THREE * hexSize);
HALF_SQRT_THREE
是我在变量中定义的常量,以避免每次渲染六边形时都重新计算它。它被定义为 Math.sqrt(3)/2.0
.
引用自webpage:
The width of a hexagon is width = sqrt(3)/2 * height. The horizontal distance between adjacent hexes is horiz = width.