2

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

在此处输入图像描述

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

在此处输入图像描述

这是 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() 时,我得到白线但没有箭头。

在此处输入图像描述

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

在此处输入图像描述

我敢肯定,我错过了一些简单的事情。提前致谢。

Update - 03.22.13

事实证明@poupou 的回答是正确的,但是,再加上我的一些其他编码“误解”,并没有立即解决我的问题。但是,由于它为我指明了解决方案的正确方向,所以我接受了他的回答。

我首先通过 Mike Bluestein在 MonoTouch 中使用 CoreGraphics 绘制的出色文章学习了如何使用 CoreGraphics 。然而,一点知识是一件危险的事情,当我开始将这些概念应用到我自己的工作中时,我无意中混合了不应该的图形上下文和路径方法。

经过大量的谷歌搜索、阅读和审查其他人的 CoreGraphics 源代码(Xamarin 的 Nina Vyedin 和 Bryan Costanich 的绘图示例的道具),我想出了一个有效的 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();
}

这是最终结果。

在此处输入图像描述

注意:我必须将 DrawArrowHead 代码从它的方法中移出并移到 UIView 的 Draw 方法中,以避免在绘制第二、第三、第四和第五行/箭头组合时出现 Invalid Context 错误(您可以在此处阅读有关该类型错误的信息) .

4

1 回答 1

1

调用path.CloseSubpath();aCGPath与调用gctx.ClosePath();a不同CGContext(将在其中完成描边/填充)。你试过后面的吗?

于 2013-03-21T12:42:24.940 回答