2014-09-28 143 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