从同一个边界框绘制的路径具有不同的半径

时间:2013-11-19 15:42:56

标签: android graphics android-canvas

背景

我正在绘制一个自定义View,它由一个弧线组成,沿着弧线绘制图像。

有点像“财富之轮”截图,其中只有大圆盘的一部分可见,并且当用户拖动视图时,图像变得可见/隐藏在适当的位置和角度沿着光盘的边缘。

Wheel of Fortune

这很好用;我使用下面的代码创建一个大的边界框(视图的宽度的四倍,以获得更微妙的弧),我使用Path.arcTo()来绘制光盘的可见上边缘。

因为边界框是方形的,所绘制的圆弧(如果我要绘制360°)将是圆形的。

// Disc dimensions (based on this View's width/height/padding)
final int radius = width * 2;
final float halfWidth = width / 2f;
final float top = mTopPadding;

// Create a large, square bounding box to draw the disc in.
// Centre horizontally; top edge of the disc == top edge of this View (+ padding)
final RectF discBounds = 
    new RectF(-radius + halfWidth, top, radius + halfWidth, radius * 2 + top);

// Create an arc along the circumference of the disc,
// but only where it will intersect with this View
double arcSweep = Math.toDegrees(Math.asin(halfWidth / radius)) * 2;
double startAngle = 180 + ((180 - arcSweep) / 2d);
mDiscPath.reset();
mDiscPath.arcTo(discBounds, (float) startAngle, (float) arcSweep);

// Close the shape so that we fill the rest of this View
// (the area underneath the arc) with the disc bg colour
mDiscPath.lineTo(width, height);
mDiscPath.lineTo(0, height);

然后我创建另一个Path并再次使用完全相同的边界框调用arcTo(),以便保持相同的圆弧半径。

这次弧的扫掠角度较长,因为View一次只能显示两个或三个图像,但屏幕外任意数量的图像(在我的情况下,向上)到十点左右。

// Create another arc, along which the images should move,
// based on the number and width of the images.
// We will later use a PathMeasure object created from
// this Path to determine where to draw each image
arcSweep = (mTotalWidth * 180) / (radius * Math.PI);
startAngle = 180 + ((180 - arcSweep) / 2d);
mImagePath.reset();
mImagePath.arcTo(discBounds, (float) startAngle, (float) arcSweep);

问题

onDraw()中,mDiscPath被绘制为背景(canvas.drawPath(mDiscPath, fillPaint)),然后根据{{1}创建的PathMeasure对象绘制相应的位图用户拖动了多远。

然而,值得注意的是,当光盘“旋转”时,图像并未精确地遵循预期的路径。这会导致问题,因为图像需要准确对准光盘的边缘。

为了排查故障,我开始使用mImagePath绘制mImagePath,以了解为什么图像路径似乎不遵循光盘路径。

在下面的屏幕截图中,为了使问题更加明显,常规位图不会在光盘顶部绘制,canvas.drawPath(mImagePath, strokePaint)向下翻译4dp(即未翻译时问题也是可见的)。

Three instances of the custom disc View

在这里,我们可以看到自定义视图的三个独立实例堆叠在一起。

但很明显,在每种情况下,黑线(mImagePath)与彩色圆盘顶部的半径(mImagePath)不匹配。即,黑弧的半径看起来比盘的半径大。

两个mDiscPath对象的弧都是使用相同的边界框创建的,所以我希望两个弧的半径相同。

底部光盘上的线条似乎匹配得很好,但前两个光盘显然是错误的 光盘之间唯一真正的区别是显示的图像数量,因此是图像路径的扫描角度(三个视图分别为89°,169°,222°)。


问题

为什么,如果使用完全相同的方形Path边界框来创建两个RectF个对象,为什么从这些路径绘制的弧具有不同的半径?

我错过了什么吗?我应该使用不同的API吗?


后记

我确保边界框的大小正确,并且在创建两条路径之间不会发生变化 在所有情况下,起始角和扫掠角看起来都是正确的(即每个弧的中点为270°) 创建全新路径或重置现有路径没有任何区别 对两个路径使用相同的弧扫描确实可以正常工作 我已经在各种设备和方向上进行了测试,无论是否有软件渲染。

0 个答案:

没有答案