2013-03-21 215 views
2

我有一些Xamarin.iOS CoreGraphics代码,它在几个不同角度的白色线条的末端绘制红色三角形。为什么CoreGraphics FillPath没有填充指定路径

enter image description here

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

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.StrokePath()与gctx.FillPath()我得到的白线,但没有箭头。

enter image description here

当我更换gctx.StrokePath()与gctx.DrawPath(CGPathDrawingMode.FillStroke)我得到的红色三角形,但是他们没有填写。

enter image description here

我我确定这很简单,我错过了。提前致谢。

Update - 03.22.13 

原来@ poupou的答案是正确的,但通过我的一些其他编码复合“误解”,没有解决我的问题的时候了。但是,由于它指出我正朝着解决方案的正确方向,我正在接受他的答案。

我第一次学会了如何通过Mike Bluestein的优秀Drawing with CoreGraphics in MonoTouch文章使用CoreGraphics。然而,一点知识是一件危险的事情,当我开始将这些概念应用到我自己的工作中时,我不经意地混合了图形上下文和路径方法。

很多谷歌上搜索,阅读和审查其他民族CoreGraphics中的源代码(道具尼娜Vyedin和Xamarin的布莱恩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的绘制方法绘制的第二,第三,第四和第五行/箭头组合时,为了避免无效的上下文错误(你可以阅读有关该类型的错误here)。

回答

1

调用上的CGPathpath.CloseSubpath();是不相同的一个CGContext(其中行程/填充将被完成)调用gctx.ClosePath();。你试过后面的吗?

+0

使用gctx.FillPath()和gctx.DrawPath(CGPathDrawingMode.FillStroke)时,使用gctx.ClosePath()替换path.CloseSubpath()会得到相同的结果。但这是一个很好的建议。 – billmaya 2013-03-21 13:14:39

+0

path.CloseSubpath在可重用路径上使用,gctx.ClosePath在绘制时从图形上下文刷新的路径上。 – billmaya 2013-03-22 09:41:59

+0

使用gctx。ClosePath是朝着正确方向迈出的一步。请参阅我原始问题中的Update - 03.22.13部分。 – billmaya 2013-03-22 12:30:59