我需要将一个动态数量的六边形(在本例中为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;中,或者还有其他我没有得到的东西。
感谢任何帮助 - 提前感谢!
编辑: 为了解释一点点 - 如果我没有抵消所有其他六边形柱(测试),我的公式就有效。我非常确定我的根本问题是我的代码是测量每个六边形需要的大小,以便在放置它们之前适合指定的矩形。然而,在它们被放置然后偏移之后,我发现六边形出现在矩形之外。哦,我的六边形也是平顶的。谢谢! 图片在下面 - 顶部是我需要的,底部是我得到的。 红色是六边形需要适合的区域:
编辑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
答案 0 :(得分: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
不适合近方区域,但{{1 }或40=5x8
可能更好)
修改强>
对于您的配置 - 平顶,第一列低于第二列:
42=6x7