如何在图形对象变换后的任意位置进行绘制?

3
我正在尝试创建一个用于绘制不同对象的画布。我使用了图形缩放和平移函数(graphics.scaleTransform和graphics.translateTransform),但是我希望画布背景(一张网格)始终填满整个窗口,但实际上并没有这样。以下是使用的代码: 编辑: 我已经尝试在转换后的图形对象中使用坐标,但它似乎不接受负数?!? 编辑: 这张图片解释了我的问题:
 public partial class Form1 : Form
        {

            PointF mouseDown;

            float newX;
            float newY;
            float zoomFactor = 1F;

            Region _rgn;
            Graphics _dc;
            PointF zoomPoint = new PointF(150, 150);

            public Form1()
            {
                InitializeComponent();

                mouseDown = new PointF(0F, 0F);

                this.panel1.Paint += new PaintEventHandler(panel1_Paint);
                this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(panel1_MouseDown);
                this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(panel1_MouseMove);

            }



            private void panel1_Paint(object sender, PaintEventArgs e)
            {

                base.OnPaint(e);

                //Graphics bg = 

                Graphics dc = e.Graphics;
                _dc = dc;

                dc.SmoothingMode = SmoothingMode.AntiAlias;

Color gridColor = Color.FromArgb(230, 230, 230);
            Pen gridPen = new Pen(gridColor, 1);

            for (float i = 0; i < this.Height * (zoomFactor); i = i + 30*zoomFactor)
            {
                dc.DrawLine(gridPen, 0, i, this.Width * (zoomFactor), i);
            }
            for (float i = 0; i < this.Width * (zoomFactor); i = i + 30*zoomFactor)
            {
                dc.DrawLine(gridPen, i, 0, i, this.Height * (zoomFactor));
            }

                dc.TranslateTransform(newX, newY);
                dc.ScaleTransform(zoomFactor, zoomFactor, MatrixOrder.Prepend);



                float XPosition = 10;
                float YPosition = 10;
                float CornerRadius = 5;
                float Width = 50;
                float Height = 50;

                Color BoxColor = Color.FromArgb(0, 0, 0);
                Pen BoxPen = new Pen(BoxColor, 2);

                GraphicsPath Path = new GraphicsPath();

                Path.AddLine(XPosition + CornerRadius, YPosition, XPosition + Width - (CornerRadius * 2), YPosition);
                Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition, CornerRadius * 2, CornerRadius * 2, 270, 90);
                Path.AddLine(XPosition + Width, YPosition + CornerRadius, XPosition + Width, YPosition + Height - (CornerRadius * 2));
                Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 0, 90);
                Path.AddLine(XPosition + Width - (CornerRadius * 2), YPosition + Height, XPosition + CornerRadius, YPosition + Height);
                Path.AddArc(XPosition, YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 90, 90);
                Path.AddLine(XPosition, YPosition + Height - (CornerRadius * 2), XPosition, YPosition + CornerRadius);
                Path.AddArc(XPosition, YPosition, CornerRadius * 2, CornerRadius * 2, 180, 90);

                Path.CloseFigure();



                LinearGradientBrush lgb = new LinearGradientBrush(new PointF(XPosition+(Width/2),YPosition), new PointF(XPosition+(Width/2),YPosition + Height), Color.RosyBrown, Color.Red);

                dc.FillPath(lgb, Path);


                dc.DrawPath(BoxPen, Path);

                Matrix transformMatrix = new Matrix();
                transformMatrix.Translate(newX, newY);
                transformMatrix.Scale(zoomFactor, zoomFactor);

                _rgn = new Region(Path);

                _rgn.Transform(transformMatrix);

            }

            private void panel1_MouseDown(object sender, EventArgs e)
            {
                MouseEventArgs mouse = e as MouseEventArgs;

                if (mouse.Button == MouseButtons.Right)
                {

                    mouseDown = mouse.Location;

                    mouseDown.X = mouseDown.X - newX;
                    mouseDown.Y = mouseDown.Y - newY;

                }

                else if (mouse.Button == MouseButtons.Left)
                {

                    if (_rgn.IsVisible(mouse.Location, _dc))
                    {
                        MessageBox.Show("tada");
                    }


                }

            }

            private void panel1_MouseMove(object sender, EventArgs e)
            {
                MouseEventArgs mouse = e as MouseEventArgs;

                if (mouse.Button == MouseButtons.Right)
                {
                    PointF mousePosNow = mouse.Location;

                    float deltaX = mousePosNow.X - mouseDown.X;
                    float deltaY = mousePosNow.Y - mouseDown.Y;

                    newX = deltaX;
                    newY = deltaY;

                    panel1.Invalidate();

                }


            }

            protected override void OnMouseWheel(MouseEventArgs e)
            {

                MouseEventArgs mouse = e as MouseEventArgs;

                PointF mP = mouse.Location;

                if (e.Delta > 0)
                {
                    if (zoomFactor >= 1 && zoomFactor <= 10)
                    {
                        zoomFactor += 1F;

                        newX = newX - ((mP.X - newX) / (zoomFactor - 1));
                        newY = newY - ((mP.Y - newY) / (zoomFactor - 1));
                    }
                    else if (zoomFactor == 0.5)
                    {
                        zoomFactor = zoomFactor * 2;
                        newX = 2 * newX - mP.X ;
                        newY = 2 * newY - mP.Y ;
                    }
                    else if (zoomFactor < 0.5)
                    {
                        zoomFactor = zoomFactor * 2;
                        newX = 2 * newX - mP.X;
                        newY = 2 * newY - mP.Y;
                    }
                }

                else if (e.Delta < 0)
                {
                    if (zoomFactor >2)
                    {
                        zoomFactor -= 1F;
                        newX = newX + (((mP.X - newX)) / (zoomFactor+1 ));
                        newY = newY + (((mP.Y - newY)) / (zoomFactor+1));
                    }
                    else if (zoomFactor == 2) {
                        zoomFactor -= 1F;

                        newX = newX + ((mP.X - newX)/2);
                        newY = newY + ((mP.Y - newY)/2);
                    }else if(zoomFactor <= 1 && zoomFactor > 0.2)
                    {
                        zoomFactor = zoomFactor / 2;

                        newX = newX + ((mP.X - newX) / 2);
                        newY = newY + ((mP.Y - newY) / 2);

                    }


                }

                panel1.Invalidate();

            }
        }

+1 表示在图片中进行编辑。 - Ron Warholic
1个回答

2
在转换坐标系之前,先画出您的网格。
如果无法在此时画出网格,则可以使用 GetTransform()ResetTransform()。之后,画上网格,在将图像转回第一步获取的那个坐标系。
个人观点:最好手动缩放图像,而不是使用坐标变换。这样可以更好地控制大小,并可以避免任何问题。
编辑:
同时,您的网格绘制程序中有一个错误:
for (float i = 0; i < this.Height * (zoomFactor); i = i + 30*zoomFactor)

尝试替换为。
for (float i = 0; i < this.Height; i = i + 30*zoomFactor)

@Daniel - 你所说的手动缩放是什么意思?是指在画布上手动缩放各个对象吗? - Bildsoe
@Daniel - 噢,我确实在缩放之前绘制了网格,但是当我将其缩小时,它不够大,特别是当我同时缩放和平移时。 - Bildsoe
是的,手动缩放和移动它们。你说的“不够大”是什么意思?此外,从你的代码中看来,在变换之前你没有绘制网格...也许如果你能提供一张“我想要的样子”和“现在的样子”的图片会更好。 - Daniel Mošmondor
@Daniel - 是的,我可以创建一些类似的图片。但现在实际发生的是网格保持原始窗口的大小。因此,如果我缩小视图,只有部分背景被网格覆盖。我尝试将代码移动到缩放之前,并仅通过将zoomFactor变量应用于它们来设置平移和缩放。但结果是相同的。另外,您能详细说明一下不手动转换它们可能会出现什么问题吗? - Bildsoe
@Daniel - 我履行了承诺,已经制作好了图片 :) - Bildsoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接