我想做的是创建一个如下所示的十六进制网格。
我可以绘制十六进制但不确定如何让它们错开。所以第一行应该是 图中的(0,0)(0,1)(0,2)(0,3)和第二行应为(1,0)(1,1)(1,2)(1,3)等行中的偶数十六进制总是错开。
目前我知道要使用的行/列数
hexRows
hexColumns
以及我如何绘制十六进制是这样的,i
就是在绘制十六进制数时对其进行编号。
DrawSolidHex(x,y,i);
当前代码如下所示
begin
hexcolumns := c;
hexrows := r;
i:=1; //first cube
x := 1; //default x,y,z values
y := 1;
z := 0;
while hexrows>0 do
begin
columnssave := hexcolumns ;
while hexcolumns >0 do
begin
DrawSoildHex(X,Y,i);
i:=i+1;
x := x + 1;
hexcolumns := hexcolumns -1;
end;
y:=y+1;
x:= 1;
z:=0;
hexcolumns := columnssave;
hexrows:= hexrows-1;
end;
totalhex := i;
目前使用此代码,它只会在直线上绘制十六进制x,y,(1,1)(2,1)(3,1)...等我不确定如何添加偏移,计算它们,并对其进行编码,以便错开行。
答案 0 :(得分:7)
在如下的六边形中,您需要了解构成边的三角形:
B B
*--* *
/| \ /|
/ | \ / |
A*--*C * ==> c / | a
\ / / |
\ / / |
*--* A*-----*C
b
这些三角形被称为30-60-90三角形,因为它构成了内角的角度:C = 90
,A = 60
,B = 30
。
这些三角形的边长比为c = 2
,b = 1
和a = sqrt(3)
。
所以,假设您知道c
(它是六边形之一的长度),您可以计算该三角形的另外两边而不必求助于三角函数:
a = c * sqrt(3) / 2
b = c / 2
一旦我们知道这些值,只需通过观察网格并使用每个六边形的最左角(上图中为A
)作为起点和终点,六角形偏移相对容易计算。
从(0,0)
到(0,1)
的水平距离为b + c + b - b
(向东北,东,东南和西南方向)。这是所有"相邻"之间的水平差异。连续的单元格,如果您只想使用b + c
,则会简化为3 * c / 2
或c
。
从(0,0)
到(0,1)
(半行)的垂直距离只是a
(东南方向不相关的东方)。这相当于sqrt(3) * c / 2
或者可能接近c * 433 / 500
(16,000中的一部分的误差),而不必涉及平方根。
虽然,如果你更喜欢准确性,你可以坚持使用平方根计算 - 只需记住在开始时计算sqrt(3) / 2
一次,然后将其用作乘数。
行之间的垂直距离显然是(0,0)
到(1,0)
的两倍。
因此,对于每一整行,您只需向下移动c * 433 / 250
单位。对于每一列,您可以移动c * 3 / 2
单位和垂直c * 433 / 500
单位(如果您从偶数索引移动到奇数索引,则向下移动,否则向上)。
答案 1 :(得分:0)
如果你知道(你应该)六角形单元的大小,你可以通过简单的计算来解决这个问题。
| small | | width | _______ ______ / \ h / \ e / \ i \ / g \ / h | \_______/ _|____t | | |--- width ---|
uses
System.Types,
Vcl.Graphics;
type
THexCellSize = record
Width : Integer;
Height : Integer;
SmallWidth : Integer;
end;
function GetHexDrawPoint( AHexCellSize : THexCellSize; ACol, ARow : Integer ) : TPoint;
begin
Result.X := ( ( AHexCellSize.Width - AHexCellSize.SmallWidth ) div 2 + AHexCellSize.SmallWidth ) * ACol;
Result.Y := AHexCellSize.Height * ARow + ( AHexCellSize.Height div 2 ) * ( ACol mod 2 );
end;
procedure DrawHexCell( ACanvas : TCanvas; AOffSet : TPoint; AHexCellSize : THexCellSize; ACol, ARow : Integer );
var
LPoint : TPoint;
LXOffset : Integer;
begin
{ *************
* 1---2
* / \
* 6 3
* \ /
* 5---4
************* }
LXOffset := ( AHexCellSize.Width - AHexCellSize.SmallWidth ) div 2;
// Move to point 1
LPoint := GetHexDrawPoint( AHexCellSize, ACol, ARow );
LPoint.Offset( AOffSet );
ACanvas.MoveTo( LPoint.X, LPoint.Y );
// Line to point 2
LPoint.Offset( AHexCellSize.SmallWidth, 0 );
ACanvas.LineTo( LPoint.X, LPoint.Y );
// Line to point 3
LPoint.Offset( LXOffset, AHexCellSize.Height div 2 );
ACanvas.LineTo( LPoint.X, LPoint.Y );
// Line to point 4
LPoint.Offset( -LXOffset, AHexCellSize.Height div 2 );
ACanvas.LineTo( LPoint.X, LPoint.Y );
// Line to point 5
LPoint.Offset( -AHexCellSize.SmallWidth, 0 );
ACanvas.LineTo( LPoint.X, LPoint.Y );
// Line to point 6
LPoint.Offset( -LXOffset, -AHexCellSize.Height div 2 );
ACanvas.LineTo( LPoint.X, LPoint.Y );
// Line to point 1
LPoint.Offset( LXOffset, -AHexCellSize.Height div 2 );
ACanvas.LineTo( LPoint.X, LPoint.Y );
end;
procedure DrawHexCellGrid( ACanvas : TCanvas; AOffSet : TPoint; AHexCellSize : THexCellSize; ACols, ARows : Integer );
var
LCol, LRow : Integer;
begin
for LRow := 0 to ARows - 1 do
for LCol := 0 to ACols - 1 do
DrawHexCell( ACanvas, AOffSet, AHexCellSize, LCol, LRow );
end;