【问题标题】:Calculate Size of Hexagons to Fit Inside Rectangle计算六边形的大小以适合矩形内部
【发布时间】:2016-04-26 21:41:18
【问题描述】:

我需要将动态数量的六边形(在本例中为 28 个)放入一个“矩形”,即用户的屏幕尺寸(在本例中为 2000 像素宽,1000 像素高)。我希望抵消所有其他列。会有一个百分比的余量。

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

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

我的问题是试图计算边。我很接近,但它似乎不太适合“矩形”,或者可能还有其他我没有得到的东西。

任何帮助表示赞赏 - 在此先感谢!

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

编辑 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

【问题讨论】:

  • 你能附上一张图片显示发生了什么错误吗?
  • 给出了什么?什么是目标参数?似乎如果您寻求边缘尺寸,并且您的公式在没有偏移的情况下有效,那么您必须忽略偏移,找到尺寸,然后减去偏移以获得最终的边缘尺寸。
  • 我已经想到了这一点,但我会从什么中减去偏移量?个人身高、体重,还是两者兼而有之?我不确定您所说的目标周长是什么意思-您是指矩形吗?在这种情况下,它将是 2(1000 + 2000),这是我在计算“边”双精度的第一部分中所做的。
  • 不是周长 - 参数。我已将十六进制边长 A 视为要找到的值。如果你计算出你可以在给定的矩形中放置 N 个边为 A 的六边形,并且想要以宽度 F 进行偏移,你必须制作 A'=A-F 的六边形
  • 我对我的问题添加了第二个编辑。它似乎使六边形太小。我认为 A=A-F 与侧面的尺寸相差太多。

标签: wpf vb.net math


【解决方案1】:

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

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 不适合接近正方形的区域,但 40=5x8 或 @ 987654328@可能会更好)

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

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

【讨论】:

  • 感谢您的回复!我在底部编辑了我的问题,以便更清楚地表达。我将尝试您的建议,但我希望所有六边形的大小都相同。我并不真正关心奇怪的空白,我只需要它们尽可能适合。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-06
相关资源
最近更新 更多