2015-08-31 74 views
0

我正在WPF中創建一個可視化工具來顯示我正在編寫的遊戲的流場信息,並且遇到了一些標籤彼此非常接近的問題。如何處理動態放置標籤的重疊

Flowfield Visualizer

在上面的屏幕截圖,扇區(0,0)是左上方。在部門(1,1)中,我突出顯示了兩個非常接近的箭頭標籤。在部門(2,1)中,我圈出了兩個完全重疊的標籤。我需要能夠以某種方式放置標籤,以便它們不重疊並具有距離邊距。我後面最好有一個簡單的算法,它允許我在競爭點上放置標籤。

藍色/黑色單元格是作爲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

考慮幾種方法來放置標籤,包括 詞雲,基於物理的方法,voronoi圖。我決定將我的方法基於An Empirical Study of Algorithms for Point-Feature Label Placement,因爲我可以看到一種簡單而快速的定位標籤的方法。我給了我一個想法,即有四個可能的位置用於所需的點,並且我用非常簡單的規則構建了我自己的實現。

我創建了一個名爲PointLabelPlacer類兩種方法 AddLabel ComputeNewPositions

,我要送我的所有標籤與指向AddLabel方法一起。 一旦我完成並準備好,我會打電話給ComputeNewPositions。這將爲所有四個可能的位置計算來自另一個標籤重疊的位置的數量。

我也會標記一個位置,如果它與另一個標籤的原點重疊。

如果兩個標籤重疊正好,我會再次選擇不重疊的第一個,但隨着使用

那我就只選擇第一個,我發現編號最小的我將標誌着所有其他標籤的位置重疊並且不與另一點重疊並且未被標記爲使用。

如果畢竟沒有其他位置可以找到,我默認左上角,並允許重疊。

這與黃色 Alternate locations displayed

顯示的替換的位置這是最後的結果 Final Result

2

有人建議

一組幾何實體的Voronoi圖是平面的劃分爲其中點比所有其他人更接近一個給定的實體的區域。 enter image description here

如果您構建曲線的Voronoi圖,並且將標籤完全放置在相應的區域中,則可以解決您的問題。

假設所有標籤具有相同的範圍(相同的邊界框),您可以通過應用erosion操作找到合適的空白區域,即在區域輪廓線上去除所需寬度/高度的像素層。其餘像素可能是標籤的中心。

在一般情況下,用幾何方法計算Voronoi圖是非常困難的。但是,如果您使用數字圖像,只需繪製幾何圖元並從中計算出distance map就足夠了。

這要求您對數字圖像處理技術有所瞭解。