如何画一定的区域

时间:2018-04-22 08:30:50

标签: c# .net graphics paint gdi+

我是c#& amp;我正在尝试制作一个简单的程序,它有3个相交的圆圈(A,B,C)。我想要做的是画一个(根据我得到的结果)。

例如:如果我得到1作为结果我想填充黄色边界区域,如果我得到4我想填充绿色边界区域等等。

Circles

我的代码来绘制这些圈子:

private void button1_Click(object sender, EventArgs e)
    {
        Graphics A = this.CreateGraphics();
        Graphics B = this.CreateGraphics();
        Graphics C = this.CreateGraphics();
        Pen Bluepen = new Pen(Color.Blue, 2);
        Pen RedPen = new Pen(Color.Red, 2);
        Pen BlackPen = new Pen(Color.Black, 2);
        A.DrawEllipse(Bluepen,100, 100, 150, 150);
        B.DrawEllipse(RedPen, 195, 100, 150, 150);
        C.DrawEllipse(BlackPen, 145, 190, 150, 150);
    }

1 个答案:

答案 0 :(得分:3)

由于你是这个话题的新手,我必须告诉你:这比人们希望的要困难得多。

我想到了三种解决方案:

  • 构建一个GraphicsPath,您可以填写三个Arcs。要计算弧线,您需要具有的矩形,以及扫描角度和起始角度。这将需要相当多的数学..

  • 在吸引Bitmap之后,您可以填充您想要着色的区域。这仅适用于可以从中提取每个像素的当前颜色的位,而不是用于绘制到控件上。

  • 最简单的方式仍然有点涉及,但只是温和地如此

解决方案3(创建区域并填写)

您可以使用各种设置操作来组合名为Regions的区域。您可以从Region构建GraphicsPath。您可以通过添加椭圆来构造GraphicsPath。您可以剪切 Graphics对象的绘图区域为Region

让我们试试:

enter image description here

private void panel1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.SmoothingMode = SmoothingMode.AntiAlias;

    Rectangle r1 = new Rectangle(100, 100, 150, 150);
    Rectangle r2 = new Rectangle(195, 100, 150, 150);
    Rectangle r3 = new Rectangle(145, 190, 150, 150);
    GraphicsPath gp1 = new GraphicsPath();
    GraphicsPath gp2 = new GraphicsPath();
    GraphicsPath gp3 = new GraphicsPath();
    gp1.AddEllipse(r1);
    gp2.AddEllipse(r2);
    gp3.AddEllipse(r3);
    Region r_1 = new Region(gp1);
    Region r_2 = new Region(gp2);
    Region r_3 = new Region(gp3);

    r_1.Intersect(r_2);   // just two of five..
    r_1.Exclude(r_3);     // set operations supported!

    g.SetClip(r_1, CombineMode.Replace);
    g.Clear(Color.Magenta);    // fill the remaining region
    g.ResetClip();

    g.DrawEllipse(Pens.Red, r1);
    g.DrawEllipse(Pens.Blue, r2);
    g.DrawEllipse(Pens.Green, r3);

   // finally dispose of all Regions and GraphicsPaths!!
    r_1.Dispose();
    gp1.Dispose();
    .....

}

请注意区域操作会更改当前区域;如果你想填补更多区域,你需要恢复更改的区域!

另请注意,我绘制了任何持久性绘图所属的位置:在Paint事件中,我使用其e.Graphics对象..

GraphicsPaths因为Regions是GDI对象,应该处理掉!

关于解决方案1的注释(按数学创建GraphicsPath)

完全数学是相当复杂的。通过做一些假设,任务可以大大简化:让我们假设圆圈具有相同的大小。另外,我们首先只看两个圆圈,具有相同的y位置。最后,圆圈形成一个对称的图形。 (他们没有这样做:红色圆圈应该有x = 190而绿色圆圈应该是y = 186,45 ..)

获得两个交叉点以及扫描角度并不是那么难。

接下来可以使用Matrix将整个图形中心周围的两个点旋转两次120°;有关示例,请参阅here。现在我们有六点;我们仍然需要较小的扫掠角度,这也可以通过简单的数学运算找到。

最后,我们可以构建12个弧中的所有12个(!)GraphicsPaths并随意组合它们。

好的部分是我们可以填充和绘制这些路径。但是,代码相当广泛..

有关解决方案2(floodfill)的说明

虽然您无法直接在控件上进行填充,但您可以在位图中准备结果,然后使用Graphics.DrawImage在控件上显示该图像。

有关洪水填充编码的示例,请参阅this post