2014-09-28 122 views
0

我正在編寫一個可視化應用程序:它從XML中加載構建幾何圖形並將其繪製在屏幕上。 建築由長方形的房間組成,其中很多 - 所以我想在他們身上畫出他們的名字。在Y軸上反轉繪製文本

我使用this教程來翻轉我的形式的Y軸,因爲建築數據存儲在笛卡爾座標。並將其全部轉換爲經典的Windows「y增長」系統,而繪圖看起來很奇怪。
另外我需要縮放並將我的「場景」翻譯爲左下角。
而且,我的痛苦最後,我需要再次翻轉我的文字 - 因爲它也會翻轉!

由於tutorial說,我需要:

  1. 翻轉Y軸,規模和移動場景所需位置
  2. 繪製建築幾何(只是矩形)在直角座標
  3. 返回到「Y增長下經典的‘系統

但COOR」制度,規模,在此再次移動

  • 繪製文本’文字的用餐無效! 。
    他們是從正確的位置:(

    所以這是我的問題下移 - 如何計算在Windows新的文本座標形式正確對象

    void VisualizerForm_Paint(object sender, PaintEventArgs e) 
    { 
        // Setup graphics output settings 
        var g = e.Graphics; 
        g.Clear(Color.White); 
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
        g.PageUnit = GraphicsUnit.Pixel; 
    
        // Move coordinate system center to the bottom left corner, 
        // scale it to user-defined scale value and flip Y axis (mul it scale to -1) 
        g.ScaleTransform(m_scale, -m_scale, MatrixOrder.Append); 
        g.TranslateTransform(50, Height - 50, MatrixOrder.Append); 
    
        // ... Draw some complex building geometry ... 
    
        // Draw building room 
        var customPen = new Pen(Color.Black, 1.0f/g.DpiX); 
        var rect = new RectangleF(box.X1, box.Y1, (box.X2 - box.X1), (box.Y2 - box.Y1)); 
        g.DrawRectangle(customPen, box.X1, box.Y1, (box.X2 - box.X1), (box.Y2 - box.Y1)); 
    
        GraphicsState gs = g.Save(); 
    
        // First reset transform matrix 
        g.ResetTransform(); 
        // Then again scale and move scene, but now with classic down-incresed Y axis 
        g.ScaleTransform(m_scale, m_scale, MatrixOrder.Append); 
        g.TranslateTransform(50, Height - 50, MatrixOrder.Append); 
    
        // All Y coords now must be inverted :/ *sigh* 
        box.Y1 *= -1.0f; 
        box.Y2 *= -1.0f; 
        rect = new RectangleF(box.X1, box.Y1, Math.Abs(box.X2 - box.X1), Math.Abs(box.Y2 - box.Y1)); 
    
        // FIXME: This text is drawing in incorrect place 
        var fnt = new Font("Arial", 40f/g.DpiX, FontStyle.Bold, GraphicsUnit.Pixel); 
        g.DrawString("ID: " + box.Id, fnt, Brushes.Black, rect, stringFormat); 
    
        g.Restore(gs); 
    } 
    
  • 回答

    1

    終於明白了!
    下面的類在其中心繪製了一個帶有指定文本的矩形 - 在Y反轉的場景中。
    文字自動縮放以適合實際的矩形大小。享受:)

    class RectangleWithText 
    { 
        RectangleF m_extent = new RectangleF(); 
        string m_text = ""; 
    
        Font m_textFont = null; 
        RectangleF m_textRect = new RectangleF(); 
    
        public RectangleWithText(RectangleF extent, string text) 
        { 
         m_extent = extent; 
         m_text = text; 
        } 
    
        public void Draw(Graphics g) 
        { 
         var dashedGrayPen = new Pen(Color.Gray, 1.0f/g.DpiX) { DashStyle = DashStyle.Dash }; 
         var brownPen = new Pen(Color.Brown, 1.0f/g.DpiX); 
    
         // Draw rectangle itself 
         g.DrawRectangle(brownPen, m_extent.X, m_extent.Y, m_extent.Width, m_extent.Height); 
    
         // Draw text on it 
         var extentCenter = new PointF((m_extent.Left + m_extent.Right)/2, (m_extent.Bottom + m_extent.Top)/2); 
         DrawText(g, m_text, extentCenter, m_extent); 
    
         } 
        } 
    
        private void DrawText(Graphics g, string text, PointF ptStart, RectangleF extent) 
        { 
         var gs = g.Save(); 
    
         // Inverse Y axis again - now it grow down; 
         // if we don't do this, text will be drawn inverted 
         g.ScaleTransform(1.0f, -1.0f, MatrixOrder.Prepend); 
    
         if (m_textFont == null) 
         { 
          // Find the maximum appropriate text size to fix the extent 
          float fontSize = 100.0f; 
          Font fnt; 
          SizeF textSize; 
          do 
          { 
           fnt = new Font("Arial", fontSize/g.DpiX, FontStyle.Bold, GraphicsUnit.Pixel); 
           textSize = g.MeasureString(text, fnt); 
           m_textRect = new RectangleF(new PointF(ptStart.X - textSize.Width/2.0f, -ptStart.Y - textSize.Height/2.0f), textSize); 
    
           var textRectInv = new RectangleF(m_textRect.X, -m_textRect.Y, m_textRect.Width, m_textRect.Height); 
           if (extent.Contains(textRectInv)) 
            break; 
    
           fontSize -= 1.0f; 
           if (fontSize <= 0) 
           { 
            fontSize = 1.0f; 
            break; 
           } 
          } while (true); 
    
          m_textFont = fnt; 
         } 
    
         // Create a StringFormat object with the each line of text, and the block of text centered on the page 
         var stringFormat = new StringFormat() 
         { 
          Alignment = StringAlignment.Center, 
          LineAlignment = StringAlignment.Center 
         }; 
         g.DrawString(text, m_textFont, Brushes.Black, m_textRect, stringFormat); 
    
         g.Restore(gs); 
        } 
    } 
    
    1

    試試這個:

    void DrawDigonalString(Graphics G, string S, Font F, Brush B, PointF P, int Angle) 
    { 
        SizeF MySize = G.MeasureString(S, F); 
        G.TranslateTransform(P.X + MySize.Width/2, P.Y + MySize.Height/2); 
        G.RotateTransform(Angle); 
        G.DrawString(S, F, B, new PointF(-MySize.Width/2, -MySize.Height/2)); 
        G.RotateTransform(-Angle); 
        G.TranslateTransform(-P.X - MySize.Width/2, -P.Y- MySize.Height/2); 
    } 
    
    +0

    隨着agjusted翻譯('g.TranslateTransform(50,身高 - 100,MatrixOrder.Append)'你發揮作用的工作很好,謝謝,我把它叫做這樣:'DrawDigonalString(克,「ID :「+ box.Id,fnt,Brushes.Black,new PointF(box.X1,-box.Y1),0)'。 PS你能簡單地解釋它是如何工作的嗎? – eraxillan 2014-09-28 06:20:17

    +0

    我發現只有一個問題:text and rectangles以不同的方式進行縮放,即小規模值的文本從其父矩形「剔除」 – eraxillan 2014-09-28 06:29:48