2013-12-13 37 views
0

我想使用Clipper庫來修改圖形路徑。如何使用Clipper庫來放大和填充路徑

我有代表輪廓/筆畫的寬度列表。我想從最大的第一個開始,並努力工作到最小。

在這個例子中,我們將增加2杆20和10

我想借此把我的圖形路徑的寬度,以及擴大/ 20個像素偏移到一個新的圖形路徑。我不想改變原來的路徑。然後我想用純色填充新的圖形路徑。

接下來,我想採取我原來的圖形路徑,並將它擴大/偏移10個像素到一個新的圖形路徑。我想用不同的顏色填充這條新路徑。

然後我想用不同的顏色填充我的原始路徑。

什麼是正確的方法來做到這一點。我創建了以下方法來嘗試並執行此操作,但它無法正常工作。

private void createImage(Graphics g, GraphicsPath gp, List<int> strokeWidths) 
{ 
    ClipperOffset pathConverter = new ClipperOffset(); 
    Clipper c = new Clipper(); 
    gp.Flatten(); 

    foreach(int strokeSize in strokeWidths) 
    { 
    g.clear(); 
    ClipperPolygons polyList = new ClipperPolygons(); 
    GraphicsPath gpTest = (GraphicsPath)gp.Clone();  
    PathToPolygon(gpTest, polyList, 100); 
    gpTest.Reset(); 

    c.Execute(ClipType.ctUnion, polyList, PolyFillType.pftPositive, PolyFillType.pftEvenOdd); 
    pathConverter.AddPaths(polyList, JoinType.jtMiter, EndType.etClosedPolygon);     
    pathConverter.Execute(ref polyList, strokeSize * 100); 

    for (int i = 0; i < polyList.Count; i++) 
    { 
     // reverses scaling 
     PointF[] pts2 = PolygonToPointFArray(polyList[i], 100); 
     gpTest.AddPolygon(pts2); 
    } 
    g.FillPath(new SolidBrush(Color.Red), gpTest); 
    } 
} 

     private void PathToPolygon(GraphicsPath path, ClipperPolygons polys, Single scale) 
     { 
      GraphicsPathIterator pathIterator = new GraphicsPathIterator(path); 
      pathIterator.Rewind(); 
      polys.Clear(); 
      PointF[] points = new PointF[pathIterator.Count]; 
      byte[] types = new byte[pathIterator.Count]; 
      pathIterator.Enumerate(ref points, ref types); 
      int i = 0; 
      while (i < pathIterator.Count) 
      { 
       ClipperPolygon pg = new ClipperPolygon(); 
       polys.Add(pg); 
       do 
       { 

        IntPoint pt = new IntPoint((int)(points[i].X * scale), (int)(points[i].Y * scale)); 
        pg.Add(pt); 
        i++; 
       } 
       while (i < pathIterator.Count && types[i] != 0); 
      } 
     } 
     private PointF[] PolygonToPointFArray(ClipperPolygon pg, float scale) 
     { 
      PointF[] result = new PointF[pg.Count]; 
      for (int i = 0; i < pg.Count; ++i) 
      { 
       result[i].X = (float)pg[i].X/scale; 
       result[i].Y = (float)pg[i].Y/scale; 
      } 
      return result; 
     } 

回答

0

雖然你已經做了一個非常合理的開始,但你的createImage()函數似乎會變得混亂。你提到想要不同的偏移量使用不同的顏色,所以你缺少一個顏色數組來匹配你的strokeWidths數組。另外,我不清楚你在裁剪(聯合)方面做了什麼,但可能沒有必要。

所以在僞代碼我建議像下面....

static bool CreateImage(Graphics g, GraphicsPath gp, 
    List<int> offsets, List<Color> colors) 
{ 
    const scale = 100; 
    if (colors.Count < offsets.Count) return false; 

    //convert GraphicsPath path to Clipper paths ... 
    Clipper.Paths cpaths = GPathToCPaths(gp.Flatten(), scale); 

    //setup the ClipperOffset object ... 
    ClipperOffset co = new ClipperOffsets(); 
    co.AddPaths(cpaths, JoinType.jtMiter, EndType.etClosedPolygon); 

    //now loop through each offset ... 
    foreach(offset in offsets, color in colors) 
    { 
     Clipper.Paths csolution = new Clipper.Paths(); 
     co.Execute(csolution, offset); 
     if (csolution.IsEmpty) break; //useful for negative offsets 
     //now convert back to floating point coordinate array ... 
     PointF[] solution = CPathToPointFArray(csolution, scale); 
     DrawMyPaths(Graphics g, solution, color); 
    } 
} 

有所爲觀看,如果你是使用越來越大的偏移,在「的foreach」繪製每個多邊形循環會隱藏以前繪製的多邊形。