Android 绘图基础:Path(绘制三角形、贝塞尔曲线、正余弦)

1,013 阅读3分钟

学习重点: 理解path的使用 理解贝塞尔曲线的绘制原理 可动正余弦的绘制

Path的简单介绍

  在 Android 绘图基础:Canvas画布——自定义View(绘制表盘、矩形、圆形、弧、渐变) 中我们可以看到Canvas的强大功能,其实Canvas还有一种绘图方式就是drawpath(),没有在上篇博客中写出这个方法就是想进行单独的介绍。我们通过Canvas 的其他方法只能绘制特定的图形,但是等我们学会了Path,我们就能够绘制任何图形了!   Path是Android为我们提供的非常有用的类,它可以预先在View上将N个点连成一条“路径”,然后调用Canvas.drawpath方法就可沿着路径绘制图形了。   

绘制三角形

既然我们要使用Path当然要先定义一个Path

private Path mpath; 1 onDraw方法中绘制

    //mpathd的起始位置
    mpath.moveTo(100, 100);
    //从起始位置划线到(200, 200)坐标
    mpath.lineTo(200, 200);
    //将mpath封闭,也可以写 mpath.lineTo(100, 100);代替
    mpath.close();
    //绘制path路径
    canvas.drawPath(mpath, Paintpath);

贝塞尔曲线

设么是贝塞尔曲线,简单的说就是通过三个点,不断地取三点连线的中点,最后近似出一条光滑的曲线。

image.png //贝塞尔曲线需要三个点(起始点 控制点 结束点)来确定 //贝塞尔曲线的起始点 mpath.moveTo(300, 300); //绘制贝塞尔曲线需要我们调用quadTo方法 //控制点 mpath.quadTo(50, 450, 300, 500); //结束点 canvas.drawPath(mpath, Paintpath); //绘制 canvas.drawPath(mpath, Paintpath); //如果为了更清楚的看出贝塞尔曲线与点的关系,可以通过drawpoint将点画出

正余弦曲线

在贝塞尔曲线的基础上我们再来理解正余弦,正余弦的绘制需要理解坐标点。绘制正余弦曲线我们需要使用rQuadTo()它的坐标都是相对的。

//其实位置 mpath.moveTo(100, 100); //rQuardto的位置是相对的 mpath.rQuadTo(20, 20, 40, 0); mpath.rQuadTo(20, -20, 40, 0);

image.png

注:这里要着重理解rQuardto的位置是相对的,像上图所示,相信看了上面的图你就会很好地理解了。

可动正余弦

image.png

思路:通过改变绘制的初始位置进行改变,相当于向一边拖拽

public class MyPathView extends View{ private int width; private int height;

private Paint Paintpath;
private Path mpath;
private Paint PaintText;
private Paint Paintpoint;
private int count;
private int size;
private Handler mhanHandler=new Handler(){
    public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
        case 0x23:
            count++;
//count至少80,根据我们画的mpath.rQuadTo()确定
        if(count>=80){
            count=0;        
        }
        size++;
        if(size>10){
            size=5;
        }
        mhanHandler.sendEmptyMessageDelayed(0x23, 200);
        //重新绘制
            invalidate();
            break;

        default:
            break;
        }

    };
};

public MyPathView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}
public MyPathView(Context context, AttributeSet attrs) {
    super(context, attrs);
    Paintpath=new Paint();
    Paintpath.setColor(Color.BLACK);
    Paintpath.setAntiAlias(true);
//  Paintpath.setStrokeWidth(5);
    Paintpath.setStyle(Style.STROKE);


    PaintText=new Paint();
    PaintText.setColor(Color.BLACK);
    PaintText.setAntiAlias(true);       
    PaintText.setTextSize(40);

    mpath=new Path();
    Paintpoint=new Paint();
    Paintpoint.setColor(Color.RED);
//  Paintpoint.setStrokeWidth(20);
    Paintpoint.setStyle(Style.STROKE);
    mhanHandler.sendEmptyMessage(0x23);
}
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    mpath.reset();
    //通过不断修改count值,让曲线动起来
    mpath.moveTo(count, 100);

    for(int i=0;i<20;i++){
        //rQuadTo
        mpath.rQuadTo(20, size, 40, 0);
        mpath.rQuadTo(20, -size, 40, 0);    
    }       
    canvas.drawPath(mpath, Paintpath);
    canvas.drawCircle(200, 100, 50, Paintpoint);

}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
}

}