计算六边形的大小以适合矩形内 [英] Calculate Size of Hexagons to Fit Inside Rectangle

查看:214
本文介绍了计算六边形的大小以适合矩形内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将需要在矩形"(也称为用户屏幕尺寸)(在此示例中为2000px宽,在此示例中为1000px高度)内放置动态数量的六边形(在此示例中为28个).我希望抵消其他每一栏.将有一个百分比保证金.

I will need to put a dynamic number of hexagons (28 in this example) inside a "rectangle" aka user's screen size (2000px width, 1000px height in this example). I wish to offset every other column. There will be a percentage margin.

我试图创建一个自定义面板,我的代码如下:

I attempted to create a custom panel, my code is below:

Protected Overrides Function MeasureOverride(ByVal availableSize As Size) As Size
    On Error Resume Next

    Dim side As Double = ((((Me.ActualHeight * 2) + (Me.ActualWidth * 2)) / 6) - Me.InternalChildren.Count) / 6
    Dim w As Double = 2 * side
    Dim h As Double = side * Math.Sqrt(3.0)

    For Each child As FrameworkElement In InternalChildren
        Dim childMaxSize = New Size(w, h)
        child.Measure(childMaxSize)
    Next

    Return availableSize
End Function

Protected Overrides Function ArrangeOverride(ByVal finalSize As Size) As Size
    On Error Resume Next

    Dim side As Double = ((((Me.ActualHeight * 2) + (Me.ActualWidth * 2)) / 6) - Me.InternalChildren.Count) / 6
    Dim w As Double = 2 * side
    Dim h As Double = side * Math.Sqrt(3.0)

    Dim x As Double = 0
    Dim y As Double = 0
    Dim shift As Boolean = True
    Dim shiftOffset As Double

    Dim offsetChild As FrameworkElement = TryCast(InternalChildren(0), FrameworkElement)
    shiftOffset = h / 2

    For i As Integer = 0 To InternalChildren.Count - 1 'For Each child As FrameworkElement In Me.InternalChildren
        Dim child As FrameworkElement = TryCast(InternalChildren(i), FrameworkElement)
        child.Margin = New Thickness(side * 0.02)

        If child IsNot Nothing Then
            Dim finalY As Double = y

            If shift Then finalY += shiftOffset

            shift = Not shift
            child.Arrange(New Rect(New Point(x, finalY), New Size(w, h)))

            x += w * 0.75
            Dim nextWidth As Double = 0

            If i + 1 < InternalChildren.Count Then nextWidth = w

            If x + nextWidth > Me.ActualWidth Then
                shift = True
                x = 0
                y += h
            End If
        End If
    Next

    Return finalSize
End Function
End Class

我的问题是尝试计算边.我已经接近了,但是在矩形"中似乎不太合适,或者也许还有其他我没有得到的东西.

My issue is trying to calculate the side. I am close, but it doesn't seem to fit quite right in the "rectangle", or perhaps there is something else I'm not getting.

感谢您的帮助-预先感谢!

Any help is appreciated - thanks in advance!

换种方式解释一下-如果我不偏移其他六边形柱(经过测试),则我的公式有效.我很确定我的根本问题是我的代码正在测量放置每个六边形以适合指定矩形所需的大小.但是,在放置它们然后偏移之后,我发现六边形出现在矩形的外面.哦,我的六角形也是平顶的.谢谢! 图片在下面-顶部是我所需要的,底部是我所得到的. 红色是六边形需要容纳的区域:

To explain a little differently - my formula works if I don't offset every other hexagon column (tested). I'm pretty sure my root issue is that my code is measuring the size each hexagon needs to be in order to fit in the specified rectangle before placing them. However, after they are placed and then offset, I'm finding the hexagons appearing out of the rectangle. Oh also my hexagons are flat-topped. Thanks! Pictures are below - top is what I need, bottom is what I'm getting. The red is the area the hexagons need to fit in:

我尝试了MBo关于side = side-offset的建议(我的偏移量是高度* 0.5).似乎使六角形太小:

EDIT 2: I attempted MBo's suggestion of side = side - offset (my offset is height * 0.5). It appears to make the hexagons too small:

Protected Overrides Function MeasureOverride(ByVal availableSize As Size) As Size
    On Error Resume Next

    Dim side As Double = ((((Me.ActualHeight * 2) + (Me.ActualWidth * 2)) / 6) - Me.InternalChildren.Count) / 6
    Dim h As Double = side * Math.Sqrt(3.0)

    'new
    side = side - (h * 0.5)
    h = side * Math.Sqrt(3.0)

    Dim w As Double = 2 * side

    For Each child As FrameworkElement In InternalChildren
        Dim childMaxSize = New Size(w, h)
        child.Measure(childMaxSize)
    Next

    Return availableSize
End Function

Protected Overrides Function ArrangeOverride(ByVal finalSize As Size) As Size
    On Error Resume Next

    Dim side As Double = ((((Me.ActualHeight * 2) + (Me.ActualWidth * 2)) / 6) - Me.InternalChildren.Count) / 6
    Dim h As Double = side * Math.Sqrt(3.0)

    'new
    side = side - (h * 0.5)
    h = side * Math.Sqrt(3.0)

    Dim w As Double = 2 * side

推荐答案

考虑具有R行,C列,垂直六边形方向(尖顶,两个垂直边),边尺寸A的密集六边形网格的边界框大小:

Consider bounding box size for dense hexagonal grid with R rows, C columns, vertical hexagons orientation (pointy topped, two vertical edges), edge size A:

Height = A/2 * (3 * R + 1)

宽度取决于配置:

具有相同C的六边形(N = R * C)的奇数行和偶数行:

Odd and even rows with the same number C of hexagons (N=R*C):

Width = A * Sqrt(3)/2 * (2 * C + 1)
E E E E
 O O O O
E E E E
 O O O O

具有C-1六边形的奇数行较短(也为R = 1情况)(N〜R *(C-1/2)):

Odd rows are shorter with C-1 hexagons (also R=1 case) (N~R*(C-1/2)):

Width = A * Sqrt(3) * C
E E E E
 O O O
E E E E

您可以应用这些公式将所需的N个十六进制数放入预定义的框WxH中吗?

Could you apply these formulas to fit needed number N of hexes into predefined box WxH?

您可能还需要考虑将N(或稍大一些)分解为R,C因数以最小化空白空间(例如,38=2x19不适合于近方形区域,但是40=5x842=6x7可能会更好)

You probably need also to consider some factorisations of N (or slightly larger number) into R, C factors to minimize empty space (for example, 38=2x19 is not suitable for near-square regions, but 40=5x8 or 42=6x7 could be better)

修改
对于您的配置-平顶,第一列低于第二列:

Edit
For your configuration - flat-topped, first column is lower than second:

BoundWidth = Side/2 * (3 * C + 1)
BoundHeight = Side * Sqrt(3)/2 * (2 + R) = Height * (R/2 + 1)

这篇关于计算六边形的大小以适合矩形内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆