2013-12-21 54 views
0

我正在使用WinForms爲模擬編寫可視化工具。可視化涉及圍繞網格移動的各種對象。是否有可能獲得縮放/翻譯的圖形對象?

到目前爲止,我正在使用擴展Panel的自定義控件,並在Paint事件過程中使用Graphics類進行自定義繪圖。然而,一個令人煩惱的地方是我經常不得不從grid座標縮放到control.DisplayRectangle座標(換句話說,在網格中佔用2個單元格的對象將佔用2 *(control.DisplayRectangle.Width/horizo​​ntalGridWidth)繪製時的像素)。

我想知道,有沒有辦法讓圖形對象爲我做這些翻譯,以便我可以在網格座標中表示我的繪圖,並讓它自動映射到物理座標?事實證明,Matrix確實是關鍵(見公認的答案)。下面是使它工作的代碼:

public SimulationPanel() { 
    this.DoubleBuffered = true; 
    this.SizeChanged += (o, e) => this.Invalidate(); 
    this.Paint += this.PaintPanel; 
} 

private void Paint(object sender, PaintEventArgs e) { 
       e.Graphics.Clear(Color.Black); 

      var fromRectangle = GetSimulationWorldCoordinates(); 
      var toRectangle = ScaleToFit(fromRectangle, this.DisplayRectangle); 

      using (var matrix = new Matrix(
          fromRectangle, 
          new[] { 
           toRectangle.Location, 
           new Point(toRectangle.Right, toRectangle.Top), 
           new Point(toRectangle.Left, toRectangle.Bottom), 
         })) 
      { 
           // draw the simulation stuff here using simulation coordinates 
       e.Graphics.Transform = matrix; 
       e.Graphics.FillRectangle(Brushes.LightBlue, toRectangle); 
       e.Graphics.DrawLine(Pens.Red, toRectangle.Location, new Point(toRectangle.Right, toRectangle.Bottom)); 
      } 
} 
+0

只要使用Graphics.ScaleTransform()。對ScaleTransform的第二個參數使用帶有負值的TranslateTransform()以反轉座標系並獲取左下角的原點。 –

回答

2

這段代碼如何?

我使用標籤而不是網格,因爲我無法知道您的網格。

using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     GraphicsPath path = new GraphicsPath(); 
     RectangleF pathRect; 

     public Form1() 
     { 
      InitializeComponent(); 

      Location = new Point(0, 0); 
      Size = new System.Drawing.Size(500, 500); 

      Label lbl1 = new Label(); 
      lbl1.Location = new Point(100, 100); 
      lbl1.Size = new System.Drawing.Size(200, 100); 
      lbl1.BorderStyle = BorderStyle.FixedSingle; 
      lbl1.Paint += new PaintEventHandler(lbl_Paint); 

      Label lbl2 = new Label(); 
      lbl2.Location = new Point(300, 200); 
      lbl2.Size = new System.Drawing.Size(100, 200); 
      lbl2.BorderStyle = BorderStyle.FixedSingle; 
      lbl2.Paint += new PaintEventHandler(lbl_Paint); 

      Controls.Add(lbl1); 
      Controls.Add(lbl2); 

      path.AddRectangle(new Rectangle(50, 50, 150, 150)); 
      path.AddEllipse(new Rectangle(25, 50, 25, 50)); 
      pathRect = path.GetBounds(); 
     } 

     void lbl_Paint(object sender, PaintEventArgs e) 
     { 
      var rect = ((Control)sender).DisplayRectangle; 

      PointF[] plgpts = new PointF[] { 
       new PointF(rect.Left, rect.Top), 
       new PointF(rect.Right - 1, rect.Top), 
       new PointF(rect.Left, rect.Bottom - 1), 
      }; 

      Graphics g = e.Graphics; 
      g.Clear(SystemColors.Control); 
      using (Matrix matrix = new Matrix(path.GetBounds(), plgpts)) 
      { 
       g.Transform = matrix; 
       g.DrawPath(Pens.Red, path); 
      } 
     } 
    } 
} 
+0

使用* using *語句處置矩陣。 –

+0

感謝您對我的文章發表評論。 – user3093781