2012-11-01 16 views
3

我有一個虛線(PointF[]),一些stringGraphics對象。現在我想在我的線上畫這個字符串。預定義行上的文本

下面是一個例子:

enter image description here

是否有任何的算法來做到這一點的最簡單的方法?

好吧,我已經嘗試@ endofzero的代碼,並修改它一點。這裏的整體解決方案(與角度和距離計算):

private static void DrawBrokenString(Graphics g, IList<PointF> line, string text, Font font) 
{ 
    g.SmoothingMode = SmoothingMode.AntiAlias; 
    g.TextRenderingHint = TextRenderingHint.AntiAlias; 
    Pen pen = new Pen(Brushes.Black); 

    for (int index = 0; index < line.Count - 1; index++) 
    { 
     float distance = GetDistance(line[index], line[index + 1]); 

     if (text.Length > 0) 
     { 
      for (int cIndex = text.Length; cIndex >= 0; cIndex--) 
      { 
       SizeF textSize = g.MeasureString(text.Substring(0, cIndex).Trim(), font); 
       if (textSize.Width <= distance) 
       { 
        float rotation = GetAngle(line[index], line[index + 1]); 

        g.TranslateTransform(line[index].X, line[index].Y); 
        g.RotateTransform(rotation); 

        if (index != line.Count - 2) 
        { 
         g.DrawString(text.Substring(0, cIndex).Trim(), font, new SolidBrush(Color.Black), 
           new PointF(0, -textSize.Height)); 
        } 
        else 
        { 
         g.DrawString(text.Trim(), font, new SolidBrush(Color.Black), 
           new PointF(0, -textSize.Height)); 
        } 

        g.RotateTransform(-rotation); 
        g.TranslateTransform(-line[index].X, -line[index].Y); 

        text = text.Remove(0, cIndex); 
        break; 
       } 
      }  
     } 
     else 
     { 
      break; 
     } 

     g.DrawLine(pen, line[index].X, line[index].Y, line[index + 1].X, line[index + 1].Y); 
    } 
} 

private static float GetDistance(PointF p1, PointF p2) 
{ 
    return (float) Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2)); 
} 

private static float GetAngle(PointF p1, PointF p2) 
{ 
    float c = (float) Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2)); 

    if (c == 0) 
     return 0; 

    if (p1.X > p2.X) 
     return (float) (Math.Asin((p1.Y - p2.Y)/c)*180/Math.PI - 180); 

    return (float) (Math.Asin((p2.Y - p1.Y)/c)*180/Math.PI); 
} 

現在我需要的只有一兩件事,完成我的問題。我不希望字符串彼此重疊。有任何想法嗎?唉唉,當我們無法繪製路徑上的字符串(因爲中斷量過多的,應行(中間的頂部)上面繪製

這裏是不必要的重疊的例子:

enter image description here

+2

輸入的字符串是「行上的某些文本」還是「某些文本」,「在行上」? –

+0

我得到整個字符串,所以「一些文本就行」:SI必須自己分割它 – Nickon

+1

您可以使用DrawString在適當的RotateTransform之後繪製旋轉的文本(更多內容請參見http://msdn.microsoft.com/zh-cn/ -us/library/a0z3f662(v = vs.100).aspx),您可以使用MeasureString方法(http://msdn.microsoft.com/zh-cn/library/system.drawing)查看字符串的寬度。 graphics.measurestring(v = VS.100)的.aspx)。這可以幫助你分割文本 – BlackBear

回答

1

下面是如何繪製文字下面虛線一個簡單的例子。

private static void DrawBrokenLine(PointF[] line, string text, Graphics g, Font font) 
    { 
     for (int index = 0; index < line.Length - 1; index++) 
     { 
      float distance = distanceBetween(line[index], line[index + 1]); 

      if (text.Length > 0) 
      { 
       for (int cIndex = text.Length; cIndex >= 0; cIndex--) 
       { 
        SizeF textSize = g.MeasureString(text.Substring(0, cIndex).Trim(), font); 
        if (textSize.Width <= distance) 
        { 
         float rotation = angleBetween(line[index], line[index + 1]); 

         g.TranslateTransform(line[index].X, line[index].Y); 
         g.RotateTransform(rotation); 

         g.DrawString(text.Substring(0, cIndex).Trim(), font, new SolidBrush(Color.Black), 
          new PointF(0, -textSize.Height)); 

         g.RotateTransform(-rotation); 
         g.TranslateTransform(-line[index].X, -line[index].Y); 

         text = text.Remove(0, cIndex); 
         break; 
        } 
       } 
      } 
      else 
       break; 
     } 
    } 

如果你想讓它在單詞之間的空格只破發,你將不得不改變它縮短了字符串時,它的方式正在測量

編輯

要固定在角落的文字重疊,我增加了它的計算:

private static void DrawBrokenLine(PointF[] line, string text, Graphics g, Font font) 
    { 
     float lastOverlap = 0; 

     for (int index = 0; index < line.Length - 1; index++) 
     { 
      float distance = distanceBetween(line[index], line[index + 1]); 

      float angleOfLines = 180; 
      if (index < line.Length - 2) 
      { 
       angleOfLines = angleBetweenLines(line[index], line[index + 1], line[index + 2]); 
      } 

      if (text.Length > 0) 
      { 
       SizeF textSize = g.MeasureString(text, font); 
       float overlap = 0; 
       if (angleOfLines < 180) 
       { 
        if (angleOfLines <= 90) 
        { 
         overlap = (textSize.Height/1.5f)/(
          Convert.ToSingle(Math.Tan((angleOfLines/2) * Math.PI/180)) 
          ); 
        } 
        else 
        { 
         overlap = Convert.ToSingle(
          Math.Sin(angleOfLines * Math.PI/180) * (textSize.Height/1.5f)); 
        } 
       } 

       for (int cIndex = text.Length; cIndex >= 0; cIndex--) 
       { 
        textSize = g.MeasureString(text.Substring(0, cIndex).Trim(), font); 

        if (textSize.Width <= distance - overlap - lastOverlap) //notice the subtraction of overlap 
        { 
         float rotation = angleBetween(line[index], line[index + 1]); 

         g.TranslateTransform(line[index].X, line[index].Y); 
         g.RotateTransform(rotation); 

         g.DrawString(text.Substring(0, cIndex).Trim(), font, new SolidBrush(Color.Black), 
          new PointF(lastOverlap, -textSize.Height)); 

         g.RotateTransform(-rotation); 
         g.TranslateTransform(-line[index].X, -line[index].Y); 

         text = text.Remove(0, cIndex); 
         break; 
        } 
       } 

       lastOverlap = overlap; 
      } 
      else 
       break; 
     } 
    } 

    private static float angleBetweenLines(PointF A, PointF B, PointF C) 
    { 
     float angle1 = 360 - angleBetween(A, B); 
     float angle2 = 360 - angleBetween(B, C); 

     if (angle1 < 0) 
      angle1 += 360; 
     if (angle2 < 0) 
      angle2 += 360; 

     float delta = 180 + angle1 - angle2; 

     if (delta < 0) 
      delta += 360; 
     if (delta > 360) 
      delta -= 360; 

     return delta; 
    } 

enter image description here

有一個與我的例子告誡:如果你注意到了,我將文本高度除以特殊數字。我遇到了MeasureString沒有爲文本返回一個精確的高度,所以我試圖手動進行更正。

關於畫線之上串(因爲太多的休息),這取決於你想如何檢測這種情況(什麼是太多了,應該在哪裏文本放置,它應該是一個角度?) 。也許如果你能提供一個這種情況的例子,你想到的將有助於澄清。

+0

謝謝,它的工作原理:)我幾乎自己做了,但有一個X-Y-offset因爲不良矩陣轉換而出現:P(我的不好)。但是你的解決方案很好:)你能檢查我的編輯嗎? – Nickon

+1

@Nickon更新了我對文本重疊的回答。 – endofzero

+0

最後一件事:D如果存在包含數百個2-3像素子線的虛線,該怎麼辦?有什麼方法可以修改它嗎?或者我應該嘗試任何算法?:S – Nickon

相關問題