计算适合矩形内六角形的大小

时间:2016-04-26 21:41:19

标签: wpf vb.net math

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

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

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

我的问题是试图计算方面。我很接近,但它似乎并不适合在&#34;矩形&#34;中,或者还有其他我没有得到的东西。

感谢任何帮助 - 提前感谢!

编辑: 为了解释一点点 - 如果我没有抵消所有其他六边形柱(测试),我的公式就有效。我非常确定我的根本问题是我的代码是测量每个六边形需要的大小,以便在放置它们之前适合指定的矩形。然而,在它们被放置然后偏移之后,我发现六边形出现在矩形之外。哦,我的六边形也是平顶的。谢谢! 图片在下面 - 顶部是我需要的,底部是我得到的。 红色是六边形需要适合的区域:

want have

编辑2: 我尝试了MBo建议的side = side - offset(我的偏移是高度* 0.5)。它似乎使六边形太小:

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

1 个答案:

答案 0 :(得分:1)

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

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

宽度取决于配置:

具有相同C数的六边形(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))的奇数行更短:

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

您是否可以应用这些公式以将所需的N个十六进制拟合到预定义的框WxH?

您可能还需要考虑将N(或稍大一些数字)的因子分解为R,C因子以最小化空间(例如,38=2x19不适合近方区域,但{{1 }或40=5x8可能更好)

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

42=6x7