Canvas.drawArc()伪像

问题描述:

我在自定义视图中在画布上绘制弧线,如下所示. PaintrectangleonDraw()之外定义,并在其中添加以简化操作.

I draw an arc on canvas in a custom view as shown below. Paint and rectangle are defined outside of onDraw() and added in there for simplicity purpose.

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    RectF rectangle = new RectF(60f, 60f, 480f, 480f);

    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setColor(0x40000000);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(120);

    canvas.drawArc(rectangle, 225f, 315f, false, paint);
}

当我在Galaxy Nexus 4.3上运行此代码时,会出现以下伪影.

When I run this code on Galaxy Nexus with 4.3, there are following artefacts.

尽管在带有4.4.4的Nexus 5上运行时没有此类伪像.

There is no such artefacts when running on Nexus 5 with 4.4.4 though.

我仅通过(225f,315f)等角度和其他一些角度观察到了这种伪像.大多数情况下,弧的形状正确.

I observed such artefacts by angles like (225f, 315f) and some other angles only. Most of the time the arc has a correct shape.

有办法避免这些伪影吗?

Is there a way to avoid those artefacts?

更新:我尝试通过setLayerType()使用软件,硬件和任何层.人工制品改变了形式,但仍然存在.

Update: I tried to use software, hardware and none layers using setLayerType(). Artefacts changed their form, but were still present.

我是*的新手,想添加评论,但不能(分数不足),所以必须将我的评论添加到答案中!

I'm a * newbie, wanted to add a comment but could not (having insufficient points) so had to put my comment in an answer !

一个奇怪的事情是,圆弧在外侧以垂直的直线超过了指定的终点位置.内在的终点似乎还可以.当然,这种情况以及其他混乱情况并不能说明导致问题的原因.

One strange thing is that the arc overshoots the specified end position with a straight vertical line at the outer side. The inner end point seems to be ok. Of course this and the other mess of lines does not tell what causes the problem.

当端角精确地为 的90度的倍数时,它似乎会出现.这看起来像是数值计算错误,浮点舍入问题等.@ kcoppock指出314.98f已经绕过了该错误.除了确切的315.0f以外,可能任何值都可以解决问题.

It seems to appear when the end angle is at exactly a multiple of 90 degrees. This looks like a numeric calculation bug, float round-off issue etc. @kcoppock remarked that 314.98f already circumvents the bug. Probably any value other than exactly 315.0f may do the trick.

如果涉及代码优化(尝试以尽可能小的线段绘制弧),另一个可行的技巧是通过将弧切成碎片来简化弧->使用多个drawArc调用,每个调用跨越一定的最大角度.候选人分别是30度,45度,90度和180度.如果关节不可见还有待观察...

If code optimization is involved (attempts to draw the arc in as little line segments as possible) another trick that may work is to simplify the arc by cutting it into pieces -> use multiple drawArc calls that each span a certain maximum angle. Candidates are 30, 45, 90 and 180 degrees. Remains to be seen if the joints will be invisible...

这是一个很长的路要走,希望这些建议中的任何一条都能奏效.

It's a bit of a long shot, hope any of these suggestions might work.