使用 FillPath 创建带孔的多边形
Using FillPath to create a polygon with holes
我有以下代码:
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 是表示多边形外边界的整数点列表(x
和 y
对),内部孔是表示侧面孔的整数点列表多边形。
现在这段代码应该绘制一个多边形,里面有很多洞。内部和外部可能作为值给出的示例:
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。
当尝试使用 exclude 方法时,如下所示:
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);
反而没有异常,只是突然死机到桌面。
我已经通过在 Paint
事件中使用它并利用我的 Form
(使用 PaintEventArgs
中的 Graphics
)尝试了您的代码。
你 Exclude
尝试实际上工作正常。我认为您的问题出在这一行:
Region.Exclude(gpe);
原因是,你的意思是
rr.Exclude(gpe);
您想从 rr
中排除 GraphicsPath
,稍后您将填写它。
通过键入 Region
,您可能会 剪切 Control
的区域。 Region
是 Control
的 属性,不是您要绘制的实例。
如果您在主 Form
中声明此方法,这将解释为什么您会遇到 "just a sudden crash to desktop",因为您正在破坏 Form
的绘图区域.
我之前一般都是加入所有内部图形,然后创建一个包含外部和内部图形的 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);
我有以下代码:
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 是表示多边形外边界的整数点列表(x
和 y
对),内部孔是表示侧面孔的整数点列表多边形。
现在这段代码应该绘制一个多边形,里面有很多洞。内部和外部可能作为值给出的示例:
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。
当尝试使用 exclude 方法时,如下所示:
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);
反而没有异常,只是突然死机到桌面。
我已经通过在 Paint
事件中使用它并利用我的 Form
(使用 PaintEventArgs
中的 Graphics
)尝试了您的代码。
你 Exclude
尝试实际上工作正常。我认为您的问题出在这一行:
Region.Exclude(gpe);
原因是,你的意思是
rr.Exclude(gpe);
您想从 rr
中排除 GraphicsPath
,稍后您将填写它。
通过键入 Region
,您可能会 剪切 Control
的区域。 Region
是 Control
的 属性,不是您要绘制的实例。
如果您在主 Form
中声明此方法,这将解释为什么您会遇到 "just a sudden crash to desktop",因为您正在破坏 Form
的绘图区域.
我之前一般都是加入所有内部图形,然后创建一个包含外部和内部图形的 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);