【问题标题】:Is it possible to get a scaled/translated graphics object?是否可以获得缩放/翻译的图形对象?
【发布时间】:2013-12-21 06:37:33
【问题描述】:

我正在使用 WinForms 为模拟编写可视化工具。可视化涉及围绕网格移动的各种对象。

到目前为止,我使用的是扩展 Panel 的自定义控件,并在 Paint 事件期间使用 Graphics 类进行自定义绘图。然而,一个令人恼火的是,我经常不得不将网格坐标从网格坐标缩放到 control.DisplayRectangle 坐标(换句话说,占用网格中 2 个单元格的对象将占用 2 * (control.DisplayRectangle.Width /绘制时的水平网格宽度)像素)。

我想知道,有没有办法让 Graphics 对象为我进行这些转换,以便我可以在网格坐标中表达我的绘图并让它自动映射到物理坐标?

事实证明,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));
            }
}

【问题讨论】:

  • 只需使用 Graphics.ScaleTransform()。使用带有负值的 TranslateTransform() ScaleTransform 的第二个参数来反转坐标系并获取左下角的原点。

标签: c# winforms graphics paintevent


【解决方案1】:

这段代码怎么样?

我使用标签而不是网格,因为我不知道您的网格。

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);
            }
        }
    }
}

【讨论】:

  • 使用 using 语句来处理矩阵。
  • 感谢您对我的文章的 cmets。
猜你喜欢
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 2012-10-26
相关资源
最近更新 更多