【问题标题】:Resize graphics to fit in PictureBox调整图形大小以适合 PictureBox
【发布时间】:2017-08-07 21:34:21
【问题描述】:

我需要在 C# 中绘制一个费马螺旋。我做到了,但我希望我的绘图能够填充到 PictureBox 中,无论实际尺寸有多大。

  public void DrawSpiral(double delta, double numCycles, int oX, int oY, SpiralType spiralType, Color color, Graphics g)
  {
        double a = Convert.ToInt32(textBox1.Text);
        Pen p = new Pen(color, 1);
        double prevX = oX;
        double prevY = oY;
        double X = oX;
        double Y = oY;
        double fi = Convert.ToInt32(textBox2.Text); 
        double radius = 0;

        while (fi <= (numCycles * 360))
        {
            fi += delta;
            if (spiralType == SpiralType.FermaPlus)
            {
                radius = a * Math.Sqrt(fi); 
            }
            else if (spiralType == SpiralType.FermaMinus)
            {
                radius = -a * Math.Sqrt(fi);
            }
            prevX = X;
            prevY = Y;
            X = (radius * Math.Cos(fi / 180 * Math.PI)) + oX;
            Y = (radius * Math.Sin(fi / 180 * Math.PI)) + oY;
            g.DrawLine(p, (float)prevX, (float)prevY, (float)X, (float)Y);
        }
    }

 private void DrawButton_Click(object sender, EventArgs e)
 {
        pictureBox1.Refresh();
        Graphics g = pictureBox1.CreateGraphics();
        DrawSpiral(2, 5, 150, 150, SpiralType.FermaPlus, Color.Blue, g);
        DrawSpiral(2, 5, 150, 150, SpiralType.FermaMinus, Color.Red, g);
  }

那么,我应该怎么做才能让我的绘图完全填充到 PictureBox 中。

【问题讨论】:

  • 那你为什么不使用图片框的大小作为绘图的边界呢?
  • @DonBoitnott 对不起,如果我问,但究竟如何?顺便说一下,drawSpir​​al中的(oX和oY)是Form中心的坐标
  • 当你在图片框上绘制图形时,坐标将相对于图片框的左上角,而不是表格的左上角。图片框是否停靠以填充整个表格?您想在图片框调整大小时缩放绘图,还是想保持增量不变并根据需要添加尽可能多的圈数以填充可用的对角线(外圆)?前者很简单,后者是一道很好的数学题。
  • @dlatikay 想要在图片框调整大小时缩放绘图
  • Graphics g = pictureBox1.CreateGraphics(); 抵达时死亡。永远不要使用CreateGraphics!使用Paint 事件进行绘图。使用graphics.TranslateTransform(w2, h2)int w2 = pbx.clientsize/2 等将绘图表面围绕原点居中。如果您愿意,可以过度绘制。最后:收集坐标并使用 DrawLines 而不是 DrawLine!

标签: c# winforms drawing picturebox


【解决方案1】:

这是一种方法:

更改DrawSpiral 的签名以包含PictureBoxClientSize 而不是一些中心坐标:

public void DrawSpiral(double delta, double numCycles, int spiralType, 
                                                       Color color, Graphics g, Size sz)

然后动态计算中心:

 int oX = sz.Width / 2;
 int oY = sz.Height / 2;
 double prevX = oX;
 double prevY = oY;
 double X = oX;
 double Y = oY;

接下来计算因子a

 a = sz.Width / 2 / Math.Sqrt( numCycles * 360);

最后从Paint事件调用only方法,传递出有效的Graphics对象:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    Size sz = pictureBox1.ClientSize;
    DrawSpiral(2, 5, SpiralType.FermaPlus, Color.Blue, g, sz);
    DrawSpiral(2, 5, SpiralType.FermaMinus, Color.Red, g, sz);
}

在调整PictureBox 的大小时,它仍然会用相同数量的循环填充该区域..:

几点说明:

  • 首先收集List&lt;Point&gt; points中的数据,然后使用DrawLines(pen, points.ToArray()),可以提高质量和性能

  • 在计算因子 a 时,我只使用了 width。使用Math.Min(sz.Width, sz.Height) 始终将其放入非方形盒子中!

  • 我保留了您的偏移量计算;但你可以改为g.TranslateTransform()..

  • PictureBox 将在 调整大小 时自行Invalidate/Refresh。如果您更改任何参数,请致电Invalidate 获取它们!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-13
    • 2021-07-20
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 2013-12-21
    相关资源
    最近更新 更多