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

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

你可能感兴趣的:(动态)