理解path,canvas画各种形状

时间:2023-02-06 13:21:47

                                               path 用法

  1. path与canvas关系

         path就是描点器它需要用画笔paint来将这些点连接起来,最后用canvas画布来展现这些图画。


   2. Path的各种方法

首先解释一下 Path.Direction dir这个参数

         用来指定添加到path中的模型(比如方形,椭圆)的闭合方向,有两个值

CCW 表示逆时针,CW 表示顺时针

        下面方法:

public void addArc (RectF oval, float startAngle, float sweepAngle)

将一段弧线加入到path中作为一个新的轮廓,该弧线由oval,startAngle,sweepAngle三者决定

public void addCircle (float x, float y, float radius, Path.Direction dir)

增加一个闭合的圆形到path中,dir表示闭合的方向  

public void addOval (RectF oval, Path.Direction dir)

增加一个闭合的矩形到path中

public void addPath (Path src, float dx, float dy)

将src平移dx,dy后添加到path当中

public void addPath (Path src)

将src添加到path当中

public void addPath (Path src, Matrix matrix)

将src通过matrix变换后添加到Path当中

public void addRect (float left, float top, float right, float bottom, Path.Direction dir)

增加一个闭合的矩形到path当中

public void addRect (RectF rect, Path.Direction dir)

增加一个闭合的矩形到path当中

public void addRoundRect (RectF rect, float[] radii, Path.Direction dir)

增加一个闭合的圆角矩形到path当中,radii表示各个角的半径点x,y,依次是左上角,右上角,右下角,左下角

public void addRoundRect (RectF rect, float rx, float ry, Path.Direction dir)

增加一个闭合的圆角矩形到path当中,rx,ry表示各个角的半径点

public void arcTo (RectF oval, float startAngle, float sweepAngle)

将一段圆弧连接到path当中,如果path的最后一个点和圆弧的第一个点不一样,那么就会先通过lineTo()将这两个点连接起来,然后再连接圆弧。当然,如果path是空的,那就会调用moveTo()把path的第一个点移到圆弧的第一个点上来

public void arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)

同上,sweepAngle的值在应用的过程中会到360求模,forceMoveTo如果是true,那么圆弧会一直显示一个新的轮廓

public void close ()

关闭当前轮廓,如果当前点和该轮廓的第一个点不一样,会自动的用一条直接连接该两点

public void computeBounds (RectF bounds, boolean exact)

计算path中控制的点的边界,将结果写入bounds中,如果Path中只有0或者1个点,那么bounds会返回(0,0,0,0)的值,exact这个变量没用

public void cubicTo (float x1, float y1, float x2, float y2, float x3, float y3)

从最后一个点开始增加一段贝塞尔曲线到path当中,接近(x1,y1),(x2,y2),同时在(x3,y3)中结束,如果这个轮廓没有调用过moveTo(),那么将会以(0,0)作为起点

public Path.FillType getFillType ()

获取path的填充方式,这定义了在内部的计算方法,默认值为WINDING

public void incReserve (int extraPtCount)

提示path将会增加extraPtCount个点,这能使path有效率的分配它的存储空间

public boolean isEmpty ()

查询path是否为空(不包括任何直线,曲线)

public boolean isInverseFillType ()

判断filltype是否为INVERSE中的一种

public boolean isRect (RectF rect)

如果path指定了一个矩形,那么返回true,并且rect将会存储path的边界值,如果没有指定一个矩形,返回false,并且忽略掉rect

public void lineTo (float x, float y)

将path的最后一个点连接点(x,y),如果path还没调用moveTo的话,将(0,0)点连接到(x,y)

public void moveTo (float x, float y)

设置下一个轮廓的第一个点

public void offset (float dx, float dy, Path dst)

将path平移dx,dy之后,将结果写到dst中,如果dst为null,那么改变后的结果直接写在当前path中

public void offset (float dx, float dy)

同上,只不过就是dst=null的情形

public void quadTo (float x1, float y1, float x2, float y2)

增加一条二次的贝塞尔曲线到path的最后一个点,接近(x1,y1),在(x2,y2)点结束。如果path没有调用moveTo来确定第一个点,那第一个点设置为(0,0)

public void rCubicTo (float x1, float y1, float x2, float y2, float x3, float y3)

跟cubicTo相同,但是参数里的这些点坐标会被考虑当前轮廓的相对位置


public void reset ()

清空Path的任何直线和曲线,让它变成空,但是不会改变filltype

public void rewind ()

rewind当前path,清除掉所有直线,曲线,但是保留它内部的数据结构,以便更好的重新使用

public void set (Path src)

用src的值替代当前path的值

public void setFillType (Path.FillType ft)

设置当前path的filltype

public void setLastPoint (float dx, float dy)

设置当前path的最后一个点

public void toggleInverseFillType ()

套住filltype的inverse状态

public void transform (Matrix matrix, Path dst)

将path进行matrix变化后,将结果保存到dst当中,如果dst=null,将结果保存到当前path当中

public void transform (Matrix matrix)

同上,相当于dst=null情形

3. 最后写一个小例子主要是用path画了一个柱形的图形

   这里只写了一个Activity

<pre name="code" class="java">public class MyActivity extends Activity {
private RelativeLayout rect;
private ChartView view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
rect= (RelativeLayout) findViewById(R.id.rect);
view=new ChartView(this);
rect.addView(view);
}



}

 

 
public class ChartView extends View {    public ChartView(Context context) {        super(context);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        Paint paint=new Paint();        paint.setColor(Color.BLUE);        paint.setStrokeWidth(2);        Path path=new Path();        path.addRect(200,100,300,500,Path.Direction.CCW);        canvas.drawPath(path,paint);        RectF rect=new RectF();      rect.set(400,150,500,500);      path.addRect(rect,Path.Direction.CCW);        canvas.drawPath(path,paint);    }


最后界面上就显现出一两个柱子了