创建一个类似缓冲区的多边形以围绕折线。

4

我找到了一个示例,可以将折线创建缓冲区以便最终得到一个多边形。

到目前为止,我发现需要使用 Minkowski Sums,但我无法理解其原始算法并将其转化为代码。

希望有C#的示例或该算法的详细步骤说明。


你需要凸多边形还是普通多边形? - Saeed Amiri
我不需要凸多边形。 - eNepper
能否使用GDI+?如果可以,那么GraphicPath.Widen+(OutLine) + GetPathData。 - MBo
2D几何类也可能适用,例如使用GetWidenedPathGeometry获取PathGeometry。 - PeskyGnat
3个回答

4
您可以使用Clipper库中的OffsetPolygons()函数,但首先需要将折线转换为多边形。方法是将折线附加到其反向副本上。但由于不允许重复顶点,因此反向副本必须排除第一个和最后一个顶点:v1,v2,...,vn, v(n-1),...,v2。

enter image description here


看起来Clipper只接受int值作为坐标,但我的坐标是double值,例如(56.30174)。或者我漏掉了什么? - eNepper
关于 int 值,请参阅此处文档中的常见问题解答:http://www.angusj.com/delphi/clipper/documentation/Docs/Overview/FAQ.htm - Angus Johnson
你知道 delta 是否被除以 2 吗?因为我的多边形的宽度与我的 delta 一样宽,而不是两倍宽。 - eNepper
如果按照上述建议将折线转换为多边形,则 delta 将是多边形在原始折线两侧扩展的量。因此,您新转换和扩展的折线的“宽度”将是 delta 的两倍。 - Angus Johnson

3
这里是使用.NET Framework中已有的2D对象来完成类似操作的示例方式,基于此链接:

http://www.charlespetzold.com/blog/2008/04/Rounded-Graphics-in-WPF.html


  // ...
  StreamGeometry geom = new StreamGeometry();

  DrawLines(geom);

  Pen p = new Pen(Brushes.Black, 10);
  p.LineJoin = PenLineJoin.Round;
  p.EndLineCap = PenLineCap.Round;
  p.StartLineCap = PenLineCap.Round;


  PathGeometry pathGeomWide = geom.GetWidenedPathGeometry(p);
  PathGeometry pathGeom = pathGeomWide.GetOutlinedPathGeometry();

  Path myPath = new Path();
  myPath.Stroke = Brushes.Black;
  myPath.Data = pathGeom;
  myCanvas.Children.Add(myPath);
  // ...

private static void DrawLines(StreamGeometry geom)
{
  using (var context = geom.Open())
  {
    context.BeginFigure(new Point(20, 20), false, true);
    context.LineTo(new Point(100, 20), true, true);
    context.LineTo(new Point(100, 100), true, true);
    context.LineTo(new Point(200, 100), true, true);
  }
}

enter image description here


1

你尝试过从Codeplex使用'Dot Spatial'库吗?

http://dotspatial.codeplex.com/

该程序内部使用Geos和Proj4库,这两个库已经包含了您所需的所有功能(世界上大多数GIS服务器和产品都是基于这两个代码库构建的!)。

如果无法使用这些库,您可以使用SQlite:

http://sqlite.phxsoftware.com/

以及Spatialite:

http://www.gaia-gis.it/spatialite/

然后使用 C# 中的 ADO.NET 代码,您可以使用简单的 GIS SQL 查询来执行处理,例如:

SELECT AsText(ST_Buffer(polyline,0.25),4326)

这将返回一个类似于字符串的东西:

MULTIPOLYGON((x y, x y, x y, x y......))

然后你可以轻松解析它。

没有必要重新发明轮子,因为你需要的一切都已经准备就绪。


只有一个问题,'Dot Spatial' 所使用的开源许可证与我正在开发的软件不兼容。 - eNepper
你需要什么类型的许可证? - shawty

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