有人可以解释一下 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 不能。有人可以解释一下吗?

图像复制在 PHP 中重新采样,有人可以解释一下吗?

有人可以解释为啥我的最后一个 else 语句不会运行吗?

有人可以解释为啥以下查询的功能不同吗?从字面上看,两者之间的唯一区别是

java中的数据源是啥?有人可以用简单的语言解释一下吗?

有人可以解释一下attr吗?