0

我正在尝试使用 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;
        }
4

1 回答 1

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”循环中绘制的每个多边形都会隐藏以前绘制的多边形。

于 2013-12-16T05:21:17.473 回答