有人可以解释一下 arcTo 的最后两个参数吗?
Posted
技术标签:
【中文标题】有人可以解释一下 arcTo 的最后两个参数吗?【英文标题】:can someone please explain the last two params of arcTo? 【发布时间】:2011-08-01 01:45:11 【问题描述】:我正在尝试绘制一个带圆角的矩形。我有一个执行此操作的 javascript 路径,但 javascript arcTo 方法采用一个矩形(定义其椭圆形),然后是一个设置扫描的参数。
但是,在 android 版本中,有三个参数。矩形椭圆形(我认为我已经正确定义了),然后是 startAngle 和 sweepAngle(我不了解它的用法),但是当我用我的方式做面条时,我的弧线看起来不像我所期望的那样我猜他们应该工作。
有人知道这方面的好教程吗?
具体来说,我想了解如果我试图从 12 到 3 绘制弧线(在钟面上),然后假设我有一条从 3 向下延伸的线,那么这两个参数会是什么样子然后需要从 3 到 6 圆角,依此类推。
这是我的代码(现在忽略其中的弧数......这只是我猜测这可能如何工作的最新迭代,在之前的更明智的尝试中失败了):
Path ctx = new Path();
ctx.moveTo(X+5,Y); //A
ctx.lineTo(X+W-5,Y);//B
ctx.arcTo(new RectF(X+W, Y, X+W, Y+5), -180, 90); //B arc
ctx.lineTo(X+W,Y+H-5); //C
ctx.arcTo(new RectF(X+W,Y+H,X+W-5,Y+H),90,180); //C arc
ctx.lineTo(X+W/2 +6,Y+H);
ctx.lineTo(X+W/2,Y+H+8);
ctx.lineTo(X+W/2-6,Y+H);
ctx.lineTo(X+5,Y+H);
ctx.arcTo(new RectF(X,Y+H,X,Y+H-5),180,270);
ctx.lineTo(X,Y+5);
ctx.arcTo(new RectF(X,Y,X+5,Y),270,0);
Paint p = new Paint();
p.setColor(0xffff00ff);
canvas.drawPath(ctx, p);
非常感谢。
【问题讨论】:
【参考方案1】:archTo 参数使用四个示例直观地解释。
public void arcTo (RectF oval,
float startAngle,
float sweepAngle,
boolean forceMoveTo)
RectF 在哪里
RectF(float left, float top, float right, float bottom)
(希望比阅读 archTo android 文档不那么痛苦和神秘)
【讨论】:
【参考方案2】:奇怪的是没有人提供答案,一旦我找到它(不容易找到),它真的很简单。
所以,它的工作方式是这样的: 假设您要在 12 - 3 处绘制圆角(使用时钟参考): 你开始你的路径,当你需要线弧时,你定义一个矩形,其左上角是你的线当前终止的地方,其右下角是你想要弧线去的地方,所以如果你想象X,Y 为 12(在时钟上)且 X+W,Y+H 为 3 的正方形,这就是您需要的正方形。
现在,假设你在那个正方形中有一个椭圆(在这个例子中它是一个圆形椭圆,如果你想让你的曲线更像椭圆,那么将你的正方形定义为一个矩形),你可以取任意切片该圆圈使用该方法的最后两个参数。第一个参数定义您要开始切割的角度。如果我们使用指南针,0 度是东(不知道为什么,我不是几何专家......这正常吗?我一直认为 0 是北,但我看到的所有编程几何示例都有 0 作为东方,也许有人会评论为什么会这样)。
第二个参数定义你想要多少圆。如果你想要整个圆圈,你可以放 360,如果你想要一半的圆圈,你可以放 180 等等。
因此,在我们的例子中,因为我们想从 12 到 3 圆角,所以我们将 270 作为我们的起始度并抓取圆的 90 度。
最后,当您完成此过程后,该线路现在认为自己在下午 3 点,因此您可以从那里继续 lineTo(ing)。 所以......这是我的形状的固定代码(它有一个小三角形,但它既不是这里也不是那里,实际的圆形部分是BC,DE,IJ和KA。其余都是直线。
int arc = 25;
public Cursor(int X, int Y, int W, int H)
/*
* A B
* K C
* J D
* I H F E
G
*/
int Ax = X+ arc;
int Ay = Y;
int Bx = X + W - arc;
int By = Y;
int Cx = X + W;
int Cy = Y + arc;
int Dx = Cx;
int Dy = (Y + arc) + (H - arc*2);
int Ex = Bx;
int Ey = Y + H;
int Fx = X+W/2 +6;
int Fy = Ey;
int Gx = X+W/2;
int Gy = Y+H+8;
int Hx = X+W/2-6;
int Hy = Ey;
int Ix = Ax;
int Iy = Hy;
int Jx = X;
int Jy = Dy;
int Kx = X;
int Ky = Cy;
Path ctx = new Path();
ctx.moveTo(Ax,Ay); //A
ctx.lineTo(Bx,By);//B
ctx.arcTo(new RectF(Bx, By, Cx, Cy), 270, 90); //B-C arc
ctx.lineTo(Dx,Dy); //D
ctx.arcTo(new RectF(Dx - arc, Dy, Ex + arc, Ey),0,90); //D-E arc
ctx.lineTo(Fx, Fy); //E-F
ctx.lineTo(Gx, Gy); //F-G
ctx.lineTo(Hx, Hy); //G-H
ctx.lineTo(Ix, Iy); //H - I
ctx.arcTo(new RectF(Jx, Jy, Ix, Iy),90,90);// I = J arc
ctx.lineTo(Kx, Ky); //K
ctx.arcTo(new RectF(Ax - arc, Ay, Kx + arc, Ky),180,90); //K - A arc
ctx.lineTo(Ax, Ay); //K
Paint p = new Paint();
p.setAntiAlias(true);
p.setColor(0xffffffff);
p.setStyle(Style.FILL);
canvas.drawPath(ctx, p);
p.setColor(0xff000000);
p.setStyle(Style.STROKE);
p.setStrokeWidth(3);
canvas.drawPath(ctx, p);
【讨论】:
想象你的弧被一个矩形包围(并一直延伸到该矩形的内部,即使只显示你想要显示的部分)。第一个参数是该点开始的椭圆内的度数,第二个参数是您希望从整个椭圆中抓取多少度作为弧线段。 这有助于但也以非常重要的方式误导。该方法不适用于一般情况并且不精确。在给定坐标的情况下,从 12 - 3 绘制弧线是通过定义一个外接时钟的矩形(不是左上角为 12/右下角为 3)并指定起始角为 270 度和扫掠角为 90 度来完成。代码不会从 B 到 C 绘制弧线,例如,从 B 开始的直线是矩形长度的一半,然后是弧线,然后是矩形长度的一半到 C 的直线。如果 B 和 C 是不是90角,它失败了。这让我开始了,所以谢谢! @GeniaS.,当然,但也许重读我上面的内容,这是相当准确的。说明我所描述内容的最快方法是像这样编辑您的代码:选择一个角,比如右上角,然后用一些明显的颜色绘制矩形。与其从 270(在矩形上)开始弧线,不如从 300 开始,例如您会注意到弧线不是从矩形的左上角开始,而是从 300 度开始。在你的矩形内接一个圆圈。您的回答意味着,如果从 A 点到 B 点画一条弧线,则应选择左上角 A、右下角 B 的矩形,但事实并非如此。 很好地解释了@GeniaS。使用模拟时钟来解释角度让一切变得轻而易举。我刚刚为我的路径对象创建了一个不到 4 行代码的披萨片。感谢您的洞察力。 "0 度是东方(不知道为什么......" - 将其视为切线,东边的切线将是一条垂直线,因此为 0 度【参考方案3】:感谢这个例子,它使参数非常清晰易懂。 从我在 Android 的开发文档中读到的内容,您可能可以省去一些“lineTo()”调用(除了点 F、G、H 的调用),因为当弧的第一个点是 arcTo 时,arcTo 会自动添加 lineTo不是画的最后一点……
至于为什么0开始东,是因为数学和三角学课一般假设0度标记是三角圆(圆心为0,0,半径为1的圆)与X轴相交的点,这是东(但是这些相同的课程通常是逆时针计算角度,所以 90 度变成北,270 是南,而在 Android 上似乎是顺时针计算角度)
【讨论】:
【参考方案4】:这里有一些示例代码(从我的一个类中拼凑而成)来绘制一个填充的圆角矩形,然后添加一个描边矩形来给它一个边框:
//Initializing some stuff
_paint = new Paint();
_rect = new RectF();
_radius = 10;
_bgColor = 0xFFFFFFFF;
_borderColor = 0xFFCCCCCC;
//Doing dimension calculations
_rect.left = 0;
_rect.top = 0;
_rect.right = this.getWidth() - 1;
_rect.bottom = this.getHeight() - 1;
//painting
//draw the background
_paint.setColor(_bgColor);
_paint.setStyle(Style.FILL_AND_STROKE);
canvas.drawRoundRect(_rect, _radius, _radius, _paint);
//draw the border
_paint.setStrokeWidth(1);
_paint.setColor(_borderColor);
_paint.setStyle(Style.STROKE);
canvas.drawRoundRect(_rect, _radius, _radius, _paint);
【讨论】:
我很欣赏这一点,但这不是我所追求的……我想了解 arcTo 方法。我的形状严格来说不是一个矩形,它的底部有一个小箭头。以上是关于有人可以解释一下 arcTo 的最后两个参数吗?的主要内容,如果未能解决你的问题,请参考以下文章
GET 请求可以加书签,而 POST 不能。有人可以解释一下吗?