Android中moveTo、lineTo、quadTo、cubicTo、arcTo详解(实例)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中moveTo、lineTo、quadTo、cubicTo、arcTo详解(实例)相关的知识,希望对你有一定的参考价值。

参考技术A 记录下moveTo、lineTo、quadTo、cubicTo、arcTo的作用,在自定义view的时候经常用到。

1、moveTo

  moveTo 不会进行绘制,只用于移动移动画笔。

  结合以下方法进行使用。

2、lineTo

  lineTo 用于进行直线绘制。

  mPath.lineTo(300, 300);

  canvas.drawPath(mPath,mPaint);

默认从坐标(0,0)开始绘制。如图:

moveTo是用来移动画笔的

把画笔移动(100,100)处开始绘制,效果如图:

3、quadTo

quadTo 用于绘制圆滑曲线,即贝塞尔曲线。

mPath.quadTo(x1, y1, x2, y2) (x1,y1) 为控制点,(x2,y2)为结束点。

同样地,我们还是得需要moveTo来协助控制。

mPath.moveTo(100,500);mPath.quadTo(300,100,600,500);

canvas.drawPath(mPath, mPaint);

效果如图:

4、cubicTo

cubicTo 同样是用来实现贝塞尔曲线的。

mPath.cubicTo(x1, y1, x2, y2, x3, y3) (x1,y1) 为控制点,(x2,y2)为控制点,(x3,y3) 为结束点。

那么,cubicTo 和 quadTo 有什么不一样呢?

官方是这么说的:

Same as cubicTo, but the coordinates are considered relative to the current point on this contour.

说白了,就是多了一个控制点而已。

然后,我们想绘制和上一个一样的曲线,应该怎么写呢?

mPath.moveTo(100,500);

mPath.cubicTo(100,500,300,100,600,500);

看看效果:

如果我们不加 moveTo 呢?

则以(0,0)为起点,(100,500)和(300,100)为控制点绘制贝塞尔曲线:

5、arcTo

arcTo 用于绘制弧线(实际是截取圆或椭圆的一部分)。

mPath.arcTo(ovalRectF, startAngle, sweepAngle) , ovalRectF为椭圆的矩形,startAngle 为开始角度,sweepAngle为结束角度。

mRectF = new RectF(10,10,600,600);mPath.arcTo(mRectF,0,90);canvas.drawPath(mPath, mPaint);

由于new RectF(10, 10, 600, 600)为正方形,又截取 0 ~ 90 度 ,则所得曲线为四分之一圆的弧线。

效果如图:

Android沿路径移动对象

【中文标题】Android沿路径移动对象【英文标题】:Android move object along a path 【发布时间】:2011-09-03 12:08:15 【问题描述】:

我创建了一个圆形路径,并在屏幕上显示如下:

public void onDraw(Canvas canvas)

        Path sPath = new Path();
        sPath.moveTo(100, 100);
        sPath.lineTo(300, 100);
        sPath.lineTo(300, 300);
        sPath.lineTo(100,300);
        sPath.lineTo(100,100);
        sPath.close();

        Paint ballPaint = new Paint();
        ballPaint.setColor(Color.GREEN);
        Paint pathPaint = new Paint();
        pathPaint.setColor(Color.BLUE);

        canvas.drawPath(sPath, ballPaint);
        canvas.drawCircle(100,100,20,pathPaint);
    

我想让圆圈沿着路径移动,我该怎么做?

【问题讨论】:

【参考方案1】:

正确的方法是使用ContraintLayout,然后在要设置动画的路径上的点之间添加一个关键帧,如下所述:https://medium.com/google-developers/defining-motion-paths-in-motionlayout-6095b874d37。

【讨论】:

【参考方案2】:

以下是我使用的动画师:

目的:沿路径“路径”移动视图“视图”

v21+:

ValueAnimator pathAnimator = ObjectAnimator.ofFloat(view, "x", "y", path)

v11+:

ValueAnimator pathAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);

pathAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() 
float[] point = new float[2];

@Override
    public void onAnimationUpdate(ValueAnimator animation) 
        float val = animation.getAnimatedFraction();
        PathMeasure pathMeasure = new PathMeasure(path, true);
        pathMeasure.getPosTan(pathMeasure.getLength() * val, point, null);
        view.setX(point[0]);
        view.setY(point[1]);
    
);

【讨论】:

如何在每个轮廓之后旋转我的视图。我有4分。我只是使用 lineto 创建路径。现在我想在这 4 个点上旋转我的观点。我该怎么做?【参考方案3】:

v21+:这会在路径上创建二次贝塞尔曲线并沿其动画 myView。

final Path path = new Path();
path.quadTo(controlX, controlY, finalX, finalY);
ObjectAnimator.ofFloat(myView, View.X, View.Y, path).start();

【讨论】:

【参考方案4】:

是的,可以沿路径移动图像。我将提供简单的解决方案来展示原理。下面的代码将沿着路径为圆圈设置动画。

int iCurStep = 0;// current animation step

@Override
protected void onDraw(Canvas canvas) 
    PathMeasure pm = new PathMeasure(sPath, false);
    float fSegmentLen = pm.getLength() / 20;//we'll get 20 points from path to animate the circle
    float afP[] = 0f, 0f;

    if (iCurStep <= 20) 
        pm.getPosTan(fSegmentLen * iCurStep, afP, null);
        canvas.drawCircle(afP[0],afP[1],20,pathPaint);
        iCurStep++;
        invalidate();
     else 
        iCurStep = 0;
    ;
;

【讨论】:

【参考方案5】:

您需要每帧将您的圆圈移动一点点朝向下一个航路点,并在到达那里后进行检测,然后开始向下一个航路点移动。据我所知,没有内置系统。

【讨论】:

以上是关于Android中moveTo、lineTo、quadTo、cubicTo、arcTo详解(实例)的主要内容,如果未能解决你的问题,请参考以下文章

MFC当中CClientDC类当中的MoveTo与LineTo的运用

Android沿路径移动对象

delphi Canvas画线问题

h5 Canvas线段的绘制

121.绘制圆

canvas基础