网络测速全解析之一:自定义View基础知识(四)

一、Path之贝塞尔曲线(非常重要~

常用速查表:

为了兼容性(偷懒) 本表格中去除了在API21(即安卓版本5.0)以上才添加的方法。忍不住吐槽一下,为啥看起来有些顺手就能写的重载方法要等到API21才添加上啊。宝宝此刻内心也是崩溃的。

作用相关方法备注
移动起点moveTo移动下一次操作的起点位置
设置终点setLastPoint重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同
连接直线lineTo添加上一个点到当前点之间的直线到Path
闭合路径close连接第一个点连接到最后一个点,形成一个闭合区域
添加内容addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别)
是否为空isEmpty判断Path是否为空
是否为矩形isRect判断path是否是一个矩形
替换路径set用新的路径替换到当前路径所有内容
偏移路径offset对当前路径之前的操作进行偏移(不会影响之后的操作)
贝塞尔曲线quadTo, cubicTo分别为二次和三次贝塞尔曲线的方法
rXxx方法rMoveTo, rLineTo, rQuadTo, rCubicTo不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)
填充模式setFillType, getFillType, isInverseFillType, toggleInverseFillType设置,获取,判断和切换填充模式
提示方法incReserve提示Path还有多少个点等待加入(这个方法貌似会让Path优化存储结构)
布尔操作(API19)op对两个Path进行布尔运算(即取交集、并集等操作)
计算边界computeBounds计算Path的边界
重置路径reset, rewind

清除Path中的内容

reset不保留内部数据结构,但会保留FillType.

rewind会保留内部的数据结构,但不保留FillType

矩阵操作transform矩阵变换

第一步.理解贝塞尔曲线的原理:

贝塞尔曲线是用一系列点来控制曲线状态的

一阶曲线原理:(其实就是lineTo())

 

二阶曲线原理:

三阶曲线原理:

cubicTo

 

二、二阶曲线讲解:

public class Bezier extends View {

private Paint mPaint;
private int centerX, centerY;

private PointF start, end, control;

public Bessel1(Context context) {
super(context);
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(8);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setTextSize(60);

start = new PointF(0,0); //数据点一
end = new PointF(0,0);  //数据点二
control = new PointF(0,0);  //控制点一
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w/2;
centerY = h/2;

// 初始化数据点和控制点的位置
start.x = centerX-200;
start.y = centerY;
end.x = centerX+200;
end.y = centerY;
control.x = centerX;
control.y = centerY-100;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// 根据触摸位置更新控制点,并提示重绘
control.x = event.getX();
control.y = event.getY();
invalidate();
return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

// 绘制数据点和控制点
mPaint.setColor(Color.GRAY);
mPaint.setStrokeWidth(20);
canvas.drawPoint(start.x,start.y,mPaint);
canvas.drawPoint(end.x,end.y,mPaint);
canvas.drawPoint(control.x,control.y,mPaint);

// 绘制辅助线
mPaint.setStrokeWidth(4);
canvas.drawLine(start.x,start.y,control.x,control.y,mPaint);
canvas.drawLine(end.x,end.y,control.x,control.y,mPaint);

// 绘制贝塞尔曲线
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(8);

Path path = new Path();

path.moveTo(start.x,start.y);
path.quadTo(control.x,control.y,end.x,end.y);

canvas.drawPath(path, mPaint);
}
}

三阶曲线:

有两个数据点和两个控制点控制曲线状态

public class Bezier2 extends View {

private Paint mPaint;
private int centerX, centerY;

private PointF start, end, control1, control2;
private boolean mode = true;

public Bezier2(Context context) {
this(context, null);

}

public Bezier2(Context context, AttributeSet attrs) {
super(context, attrs);

mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(8);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setTextSize(60);

start = new PointF(0, 0);
end = new PointF(0, 0);
control1 = new PointF(0, 0);
control2 = new PointF(0, 0);
}

public void setMode(boolean mode) {
this.mode = mode;
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w / 2;
centerY = h / 2;

// 初始化数据点和控制点的位置
start.x = centerX - 200;
start.y = centerY;
end.x = centerX + 200;
end.y = centerY;
control1.x = centerX;
control1.y = centerY - 100;
control2.x = centerX;
control2.y = centerY - 100;

}

@Override
public boolean onTouchEvent(MotionEvent event) {
// 根据触摸位置更新控制点,并提示重绘
if (mode) {
control1.x = event.getX();
control1.y = event.getY();
} else {
control2.x = event.getX();
control2.y = event.getY();
}
invalidate();
return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//drawCoordinateSystem(canvas);

// 绘制数据点和控制点
mPaint.setColor(Color.GRAY);
mPaint.setStrokeWidth(20);
canvas.drawPoint(start.x, start.y, mPaint);
canvas.drawPoint(end.x, end.y, mPaint);
canvas.drawPoint(control1.x, control1.y, mPaint);
canvas.drawPoint(control2.x, control2.y, mPaint);

// 绘制辅助线
mPaint.setStrokeWidth(4);
canvas.drawLine(start.x, start.y, control1.x, control1.y, mPaint);
canvas.drawLine(control1.x, control1.y,control2.x, control2.y, mPaint);
canvas.drawLine(control2.x, control2.y,end.x, end.y, mPaint);

// 绘制贝塞尔曲线
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(8);

Path path = new Path();

path.moveTo(start.x, start.y);
path.cubicTo(control1.x, control1.y, control2.x,control2.y, end.x, end.y);

canvas.drawPath(path, mPaint);
}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值