2011-11-22 151 views
3

我環顧四周以找到如何創建多邊形並在其周圍創建緩衝區的示例,因此我最終得到了一個多邊形。圍繞折線創建一個多邊形,如緩衝區

到目前爲止,我發現我需要Minkowskis Sums來這樣做,但是我無法理解原始算法並將其轉化爲代碼。

我寧願在C#中的例子或算法的演練。

+0

你需要凸多邊形還是多邊形? –

+0

我不需要凸多邊形。 – eNepper

+0

可以使用GDI +嗎?如果是,則GraphicPath.Widen +(OutLine)+ GetPathData – MBo

回答

4

您可以使用Clipper庫中的OffsetPolygons()函數,但首先需要將多段線轉換爲多邊形。通過在多段線上附加多段線的反向副本來完成此操作。但由於不允許重複的頂點,所以反向副本必須排除第一個和最後一個頂點:v1,v2,...,vn,v(n-1),...,v2。

enter image description here

+0

它看起來像Clipper只將int值作爲座標,但我的座標是雙倍值,例如。 (56.30174)。或者我錯過了一些東西? – eNepper

+0

有關int值,請參閱此處文檔中的常見問題解答:http://www.angusj.com/delphi/clipper/documentation/Docs/Overview/FAQ.htm –

+0

您知道三角洲除以2還是?因爲我的多邊形和我的三角形一樣寬,而不是寬度的兩倍。 – eNepper

1

您是否嘗試過使用Codeplex的'Dot Spatial'庫?

http://dotspatial.codeplex.com/

使用GEOS & Proj4內部,其中已經包含了所有你需要的功能(世界上大多數GIS服務器&產品都是建立在這兩個代碼庫!)的

做不到這一點,你可以使用SQLite:

http://sqlite.phxsoftware.com/

和Spatialite:

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

然後使用ADO.NET代碼在C#中,你可以使用簡單的GIS SQL查詢來執行你的處理EG:

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

這將返回一個字符串,像這樣:

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

那你就可以解析了。

當您需要的所有東西都隨時可用時,無需重新發明車輪。

+0

一個問題是,'Dot Spatial'獲得許可的開源許可與我正在使用的軟件不兼容。 – eNepper

+0

你需要什麼樣的許可證? – shawty

3

這裏有一個樣品的方式做這樣的事情與2D對象已經可以使用.NET Framework,以關閉此鏈接

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