【问题标题】:Using FillPath to create a polygon with holes使用 FillPath 创建带孔的多边形
【发布时间】:2016-01-04 12:30:56
【问题描述】:

我有以下代码:

using (var gp = new GraphicsPath())
{    
    var outer = new PointF[outerpoly.Count];
    for (int i = 0; i < outerpoly.Count; i++)
    {
        outer[i] = new PointF(((int)(scale * outerpoly[i].X - xmin)), (int)(scale * (outerpoly[i].Y + -ymin)));
    }
    gp.AddPolygon(outer);
    foreach (var hole in insideholes)
    {
        if (hole.Count < 3) continue;
        var inner = new PointF[hole.Count];
        for (int i = 0; i < hole.Count; i++)
        {
            inner[i] = new PointF(((int)(scale * hole[i].X - xmin)), (int)(scale * (hole[i].Y + -ymin)));
        }
        gp.AddPolygon(inner);
    }
    Graphics.FromImage(e).FillPath(color, gp);
}

其中 outerpoly 是代表多边形外边界的 intpoints 列表(xy 对),而 inside hole 是代表多边形侧面孔洞的 intpoints 列表。

现在这段代码应该画一个多边形,里面有很多洞。可以将内部和外部作为值给出的示例:

outer
{System.Drawing.PointF[4]}
    [0]: {X=-289, Y=971}
    [1]: {X=-289, Y=0}
    [2]: {X=734, Y=971}
    [3]: {X=-289, Y=971}
inner
{System.Drawing.PointF[4]}
    [0]: {X=-158, Y=797}
    [1]: {X=189, Y=568}
    [2]: {X=-158, Y=568}
    [3]: {X=-158, Y=797}

现在这段代码的结果是只绘制了外部而忽略了孔。知道为什么吗?

代码基于question

当尝试使用排除方法时,如下所示:

var outer = new PointF[outerpoly.Count];
for (int i = 0; i < outerpoly.Count; i++)
{
    outer[i] = new PointF(((int)(scale * outerpoly[i].X - xmin)), (int)(scale * (outerpoly[i].Y + -ymin)));
}
var gp = new GraphicsPath();
gp.AddPolygon(outer);
Region rr = new Region(gp);

foreach (var hole in insideholes)
{
    if (hole.Count < 3) continue;
    var inner = new PointF[hole.Count];
    for (int i = 0; i < hole.Count; i++;)
    {
        inner[i] = new PointF(((int)(scale * hole[i].X - xmin)), (int)(scale * (hole[i].Y + -ymin)));
    }
    var gpe = new GraphicsPath();
    gpe.AddPolygon(inner);
    Region.Exclude(gpe);
    gpe.Dispose();
}
gp.Dispose();

Graphics.FromImage(e).FillRegion(color, rr);
rr.Dispose();

这在Region.Exclude(gpe);线上崩溃了,没有例外,只是桌面突然崩溃。

【问题讨论】:

  • 听起来像是 this 的骗子(注:vb.net)。尝试使用StartFigure
  • 那个问题涉及的是 Visual Basic 而不是 C#。我该如何翻译呢?
  • 这就是我不投票关闭它的原因。尝试从那里接受的答案。如果它适合你,那么为未来的C#-only 程序员发布答案。
  • 我也是基于stackoverflow.com/questions/4021078/…,所以我希望我能找出我做错了什么(我的vb真的很糟糕)
  • 更像this one。很抱歉与 wpf 混淆。如果您为其他人准备mcve 会更容易:1) 重现问题 2) 尝试解决问题。

标签: c# geometry drawing draw gdi+


【解决方案1】:

我通常会在之前加入所有内部图形,然后创建一个包含外部和内部的 GraphicsPath。
默认填充模式会填充孔。

我使用 Clipper 加入多边形:
http://www.angusj.com/delphi/clipper.php

如果需要裁剪外层,需要创建裁剪区域:
https://msdn.microsoft.com/en-us/library/155t36zz(v=vs.110).aspx

        Graphics g = e.Graphics;
        var path = new GraphicsPath();

        Rectangle outer = new Rectangle(100, 100, 300, 300);
        Rectangle inner = new Rectangle(150, 150, 200, 200);

        path.AddRectangle(outer);
        path.AddRectangle(inner);

        var brush = new SolidBrush(Color.Blue);
        g.FillPath(brush, path);

【讨论】:

    【解决方案2】:

    我已经通过在Paint 事件中使用您的代码并利用我的Form(使用来自PaintEventArgsGraphics)来尝试您的代码。
    Exclude尝试实际上工作正常。我认为您的问题出现在这一行:

    Region.Exclude(gpe);
    

    其实你的意思是

    rr.Exclude(gpe);
    

    您想从您的rr 中排除GraphicsPath,稍后您将填写。
    通过输入Region,您可能切割了Control 的区域RegionControl 的属性,而不是您要绘制的实例。
    如果您在主 Form 中声明此方法,这将解释为什么您会遇到 “只是桌面突然崩溃”,因为您正在破坏 Form 的绘图区域。

    【讨论】:

      猜你喜欢
      • 2017-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2016-10-06
      • 1970-01-01
      • 2016-05-07
      相关资源
      最近更新 更多