D3D标注动态避让

原来也思考了该如何实现标注动态避让,认为必须得计算字符串所占的大小。如果在屏幕上要计算屏幕象素之类的东西。

今天总算找到了实现方法,在C# WorldWind中的KMLImporter类中有。关键是Font的如下方法:

public Rectangle MeasureString(Sprite sprite, string text, DrawTextFormat format, Color color);

public Rectangle MeasureString(Sprite sprite, string text, DrawTextFormat format, int color);

 1 if(icon.Name != null)
 2                 {
 3                     // Render name field
 4                     const int labelWidth = 1000; // Dummy value needed for centering the text
 5                     if(iconTexture==null)
 6                     {
 7                         // Center over target as we have no bitmap
 8                         Rectangle realrect = drawArgs.defaultDrawingFont.MeasureString(m_sprite, icon.Name, DrawTextFormat.WordBreak, color);
 9                         realrect.X = (int)projectedPoint.X - (labelWidth>>1);
10                         realrect.Y = (int)(projectedPoint.Y - (drawArgs.defaultDrawingFont.Description.Height >> 1));
11 
12                         bool bDraw = true;
13 
14                         foreach (Rectangle drawnrect in labelRectangles)
15                         {
16                             if (realrect.IntersectsWith(drawnrect))
17                             {
18                                 bDraw = false;
19                                 break;
20                             }
21                         }
22 
23                         if (bDraw)
24                         {
25                             labelRectangles.Add(realrect);
26                             drawArgs.defaultDrawingFont.DrawText(m_sprite, icon.Name, realrect, DrawTextFormat.Center, color);
27                         }
28                     }
29                     else
30                     {
31                         // Adjust text to make room for icon
32                         int spacing = (int)(icon.Width * 0.3f);
33                         if(spacing>10)
34                             spacing = 10;
35                         int offsetForIcon = (icon.Width>>1) + spacing;
36 
37                         // Text to the right
38                         Rectangle rightrect = drawArgs.defaultDrawingFont.MeasureString(m_sprite, icon.Name, DrawTextFormat.WordBreak, color);
39                         rightrect.X = (int)projectedPoint.X + offsetForIcon;
40                         rightrect.Y = (int)(projectedPoint.Y - (drawArgs.defaultDrawingFont.Description.Height >> 1));
41 
42                         // Text to the left
43                         Rectangle leftrect = drawArgs.defaultDrawingFont.MeasureString(m_sprite, icon.Name, DrawTextFormat.WordBreak, color);
44                         leftrect.X = (int)projectedPoint.X - offsetForIcon - rightrect.Width;
45                         leftrect.Y = (int)(projectedPoint.Y - (drawArgs.defaultDrawingFont.Description.Height >> 1));
46 
47                         bool bDrawRight = true;
48                         bool bDrawLeft = true;
49 
50                         foreach (Rectangle drawnrect in labelRectangles)
51                         {
52                             if (rightrect.IntersectsWith(drawnrect))
53                             {
54                                 bDrawRight = false;
55                             }
56                             if (leftrect.IntersectsWith(drawnrect))
57                             {
58                                 bDrawLeft = false;
59                             }
60                             if (!bDrawRight && !bDrawLeft)
61                             {
62                                 break;
63                             }
64                         }
65 
66                         if (bDrawRight)
67                         {
68                             labelRectangles.Add(rightrect);
69                             drawArgs.defaultDrawingFont.DrawText(m_sprite, icon.Name, rightrect, DrawTextFormat.WordBreak, color);
70                         }
71                         else if (bDrawLeft)
72                         {
73                             labelRectangles.Add(leftrect);
74                             drawArgs.defaultDrawingFont.DrawText(m_sprite, icon.Name, leftrect, DrawTextFormat.WordBreak, color);
75                         }
76                     }
77                 }
View Code

这种方式实现简单,但是会造成先添加到标注字符串集合的文字优先显示。索引靠后的文字始终被隐藏。

原文地址:https://www.cnblogs.com/yhlx125/p/4534219.html