gpt4 book ai didi

android - Canvas 的 drawLine 和 drawRect 不包括结束位置?

转载 作者:可可西里 更新时间:2023-11-01 19:07:08 26 4
gpt4 key购买 nike

令我惊讶的是,我刚刚发现 drawLine 和 drawRect 不包括结束位置,即:

canvas.drawLine(100, 100, 100, 100, paint);

RectF rect = new RectF(100, 100, 100, 100);
canvas.drawRect(rect, paint);

不会画任何东西。

我的paint定义如下:

Paint paint = new Paint();
paint.setAntiAlias(false);
paint.setStyle(Paint.Style.FILL);
return paint;

我试过将我的绘画定义为 FILL_AND_STROKE,但没有用。

Android 的 drawPaint() javadoc 甚至没有列出 stopX 和 stopY 参数!

因此,如果我想绘制一条从 beginY 到 endY(含)的垂直线,我必须执行以下操作:

canvas.drawLine(constX, beginY, constX, endY + 1)

请注意,我没有将 1 添加到结束 X 位置,仅添加到结束 Y(x 保持不变,因为我想要一条垂直线)。

我的设备是 HTC SENSE。

编辑:Simon,你是对的,我只是想分享我对 Android 在基本绘图这样的基本情况下没有按照其文档所说的那样做的惊讶,而不是问一个问题,并确保我在路上没有犯任何愚蠢的错误。

为了让自己更清楚:drawRect 的 javadoc 说:

public void drawRect (float left, float top, float right, float bottom, Paint paint)

Draw the specified Rect using the specified paint. The rectangle will be filled or framed based on the Style in the paint.

left - The left side of the rectangle to be drawn

top - The top side of the rectangle to be drawn

right - The right side of the rectangle to be drawn

bottom - The bottom side of the rectangle to be drawn

paint - The paint used to draw the rect

所以,在写作的时候

canvas.drawRect(x1, y1, x2, y2)

您期望一个角点位于 (x1, y1) 的矩形; (x1, y2); (x2, y1) 和 (x2, y2)。

Android 说:错了!他们将在(x1,y1); (x1, y2-1); (x2-1, y1) 和 (x2-1, y2-1)。

对于好奇的人:设置 Canvas 裁剪:

canvas.clipRect(x1, y1, x2, y2)

然后尝试画一个点:

canvas.drawPoint(x1, y1, paint);

然后您在屏幕上得到一个点。

然后在对角尝试:

canvas.drawPoint(x2, y2, paint);

没有出现。其余 2 个角也不会出现任何内容:

canvas.drawPoint(x1, y2, paint);


canvas.drawPoint(x2, y2, paint);

仍然对你们感到惊讶吗?

因此结论是 Android 将rightbottom 坐标视为独占,这意味着例如写作时:

canvas.clipRect(x1, y1, x2, y2)

您将获得 (x1, y1, x2 - 1, y2 - 1) 的裁剪范围。这同样适用于采用底部 坐标或Rect/RectF 对象的所有方法。

最佳答案

您的问题揭示了 Android 绘图 API 中的不一致。你说

So, if I want to draw a vertical line that goes exactly from beginY to endY (inclusive), I have to do the following:

canvas.drawLine(constX, beginY, constX, endY + 1)

Notice that I didn't add 1 to the ending X position, only to ending Y (xstays the same as I want a vertical line).

我认为括号中的句子是理解不一致性质的关键:

您还可以将 1 添加到结束的 X 位置(甚至是开始的 X 位置!),并且您将得到完全相同的像素方向的线。这是为什么?因为从 Android 的“左像素入/右像素出”概念转换为“开始和结束像素入”概念的底层算法如下(仅针对 x 显示,对于 y 是相同的):

int left, top, right, bottom; // left/top pixel inclusive, right/bottom pixel exclusive
int x1, y1, x2, y2; // x1/y1 and x2/y2 pixels inclusive

if ( left == right ) {
x1 = x2 = left;
} else if ( left < right ) {
x1 = left;
x2 = right - 1;
} else {
x1 = right;
x2 = left - 1;
}

这个(在我看来次优)转换的结果是这条线

canvas.drawLine(150, 150, 149, 160, paint);

完全平行于

canvas.drawLine(150, 150, 151, 160, paint);

我认为每个人都会期待某种倒 V,因为端点至少相隔 1 个像素(它们的距离是两个像素)并且起点相同。

但在各种设备和 Android 版本上进行测试,第一条完全垂直的线位于像素列 149 中,第二条垂直线位于像素列 150 中。

顺便说一句:使用“开始和结束像素”概念的正确转换是:

int x1, y1, x2, y2;           // x1/y1 and x2/y2 pixels inclusive

if ( x1 <= x2 )
++x2;
else
++x1;
if ( y1 <= y2 )
++y2;
else
++y1;
canvas.drawLine(x1, y1, x2, y2, paint);

关于android - Canvas 的 drawLine 和 drawRect 不包括结束位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8965129/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com