为什么CoreGraphics FillPath不填充指定的路径

时间:2013-03-21 10:27:33

标签: core-graphics xamarin.ios

我有一些Xamarin.iOS CoreGraphics代码,它在不同角度的几条白线的末端绘制红色三角形。

enter image description here

我希望填充红色三角形而不是渲染为轮廓但是当我使用图形上下文命令FillPath()而不是StrokePath()时,红色三角形不会出现。

enter image description here

这是DrawArrowHead代码(在绘制每条线之后由线条图代码调用)。

private void DrawArrowHead(PointF[] line, int size)
{
    // Create the arrowhead and the lines from individual arrowhead points
    PointF[] arrowhead = new PointF[] {
        new PointF(0.0f - size, 0.0f),
        new PointF(0.0f, 0.0f - size),
        new PointF(0.0f + size, 0.0f)
    };

    PointF[] line1 = new PointF[] {new PointF(arrowhead[0].X, arrowhead[0].Y), new PointF(arrowhead[1].X, arrowhead[1].Y)};
    PointF[] line2 = new PointF[] {new PointF(arrowhead[1].X, arrowhead[1].Y), new PointF(arrowhead[2].X, arrowhead[2].Y)};
    PointF[] line3 = new PointF[] {new PointF(arrowhead[2].X, arrowhead[2].Y), new PointF(arrowhead[0].X, arrowhead[0].Y)};

    // Begin drawing the arrowhead
    gctx.SaveState();

    UIColor.Red.SetStroke();
    gctx.SetFillColor(UIColor.Red.CGColor);

    gctx.BeginPath();

    double angleInRadians = Math.Atan2 (line[0].Y - line[1].Y, line[0].X -line[1].X);

    gctx.TranslateCTM(line[1].X, line[1].Y);
    gctx.RotateCTM((float)(angleInRadians -  Math.PI / 2));

    path.AddLines(line1);
    path.AddLines(line2);
    path.AddLines(line3);

    path.CloseSubpath();

    gctx.AddPath(path);

    gctx.StrokePath();

    gctx.RestoreState();
}

当我用gctx.FillPath()替换gctx.StrokePath()时,我得到白线但没有箭头。

enter image description here

当我用gctx.DrawPath(CGPathDrawingMode.FillStroke)替换gctx.StrokePath()时,我得到红色三角形,但它们没有被填充。

enter image description here

我确信这很简单,我很想念。提前谢谢。

Update - 03.22.13

原来@poupou的答案是正确的,但是由于我的其他编码“误解”而更加复杂,并没有立即解决我的问题。但是,由于它指出了我正在朝着解决方案的方向发展,我正在接受他的回答。

我首先通过Mike Bluestein的优秀Drawing with CoreGraphics in MonoTouch帖子了解了如何使用CoreGraphics。然而,一点点知识是一件危险的事情,当我开始将这些概念应用到我自己的工作中时,我无意中混淆了图形上下文和路径方法。

经过大量的谷歌搜索,阅读和审查其他人的CoreGraphics源代码(向Xamarin的Nina Vyedin和Bryan Costanich提供他们的绘图sample的道具),我提出了一个可行的DrawArrowhead方法。

private void DrawArrowHead(PointF[] line, int size)
{
    gctx.SaveState();
    UIColor.Red.SetStroke();
    UIColor.Red.SetFill();
    double angleInRadians = Math.Atan2 (line[0].Y - line[1].Y, line[0].X -line[1].X);

    gctx.BeginPath();
    gctx.TranslateCTM(line[1].X, line[1].Y);
    gctx.RotateCTM((float)(angleInRadians -  Math.PI / 2));

    PointF[] arrowhead = new PointF[] {
        new PointF (0.0f - arrowHeadSize, 0.0f),
        new PointF (0.0f, 0.0f - arrowHeadSize),
        new PointF (0.0f + arrowHeadSize, 0.0f)
    };

    gctx.MoveTo(arrowhead[0].X, arrowhead[0].Y);
    gctx.AddLineToPoint(arrowhead[1].X, arrowhead[1].Y);
    gctx.AddLineToPoint(arrowhead[2].X, arrowhead[2].Y);

    gctx.ClosePath();                   
    gctx.DrawPath(CGPathDrawingMode.FillStroke);                                   
    gctx.RestoreState();
}

这是最终结果。

enter image description here

注意:我必须将DrawArrowHead代码移出它的方法并移入我的UIView的Draw方法,以避免在绘制第二,第三,第四和第五行/箭头组合时出现无效上下文错误(您可以阅读该类型的错误here)。

1 个答案:

答案 0 :(得分:1)

path.CloseSubpath();上拨打CGPath与在gctx.ClosePath();上调用CGContext并不相同(将在其中执行笔划/填充)。你试过晚了吗?