我正在WPF中创建一个可视化工具来显示我正在编写的游戏的流场信息,并且遇到了一些标签彼此非常接近的问题。
在上面的屏幕截图中,扇区(0,0)是左上角。在扇区(1,1)中,我突出显示了两个箭头彼此非常接近的标签。在扇区(2,1)中,我圈出了两个完全重叠的标签。我需要能够以某种方式放置标签,使它们不重叠并具有距离。我最好是一个简单的算法,允许我在竞争地点放置标签。
蓝色/黑色单元格是Items Control上的虚拟化项目,画布为ItemsPanel。红色扇形方块位于一个装饰器上,而绿色线条,方框,贝塞尔曲线和红色成本标签位于第二个装饰器上。两个装饰者都使用绘图上下文以及在渲染时动态创建的所有内容。
var typeface = new Typeface(new FontFamily("Segoe UI"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
var formattedText = new FormattedText(curve.Cost.ToString(), CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, typeface, 12, Brushes.Red, null, TextFormattingMode.Display);
var textLocation = new Point(midPoint2.X - (formattedText.WidthIncludingTrailingWhitespace / 2), midPoint2.Y - formattedText.Height);
drawingContext.DrawText(formattedText, textLocation);
答案 0 :(得分:2)
建议:
一组几何实体的Voronoi图是将平面划分为点,其中点更靠近给定实体而不是所有其他实体。
如果构建曲线的Voronoi图,并且将标签完全放在相应的区域中,这可以解决您的问题。
假设所有标签具有相同的范围(相同的边界框),您可以通过应用erosion操作找到合适的空白空间,即在区域轮廓上移除所需宽度/高度的像素层。其余像素可能是标签的中心。
在一般情况下,通过几何方法计算Voronoi图非常困难。但是如果你使用数字图像,那么绘制几何实体并从中计算distance map就足够了。
这要求您对数字图像处理技术有所了解。
答案 1 :(得分:0)
考虑了几种放置标签的方法 词云,基于物理的方法,voronoi图。我决定将我的方法建立在An Empirical Study of Algorithms for Point-Feature Label Placement上,因为我可以看到一种简单快捷的标签定位方法。第2页让我想到了为期望点提供了四个可能的位置,并且我使用非常简单的规则构建了自己的实现。
我用两种方法创建了一个名为PointLabelPlacer的类 AddLabel ComputeNewPositions
我会将所有标签和点一起发送到AddLabel方法。 一旦我完成并准备就绪,我会调用ComputeNewPositions。这将使所有四个可能的位置计算来自另一个重叠的标签的位置数。
如果它与另一个标签的原始点重叠,我也会标记一个位置。
如果两个标签完全重叠,我会再次选择没有重叠的第一个标签,但我会将所有其他标签位置标记为已使用
然后我会选择我找到的第一个重叠次数最少且没有重叠另一个点并且未标记为已使用的那个。
如果找不到替代位置,我默认为左上角并允许重叠。