- 一.绘制一阶
- 二.绘制二阶和三阶
- 三.绘制辅助线和控制点
- 四.勾股定理:碰撞测试
- 1.碰撞测试
- 2.事件处理
- 3.全部代码
一.绘制一阶
public class BezierView extends View { private Path mPath;//路径 private Paint mPaint;//画笔 //java代码 public BezierView(Context context) { super(context); initPaint(); } //xml布局 public BezierView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initPaint(); } public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } private void initPaint() { //画笔 mPaint = new Paint(); //设置样式 STROKE:空心 FILL:实心 mPaint.setStyle(Paint.Style.STROKE); //设置宽度 mPaint.setStrokeWidth(20); //抗锯齿 mPaint.setAntiAlias(true); //防抖动 mPaint.setDither(true); //路径 mPath = new Path(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制一阶曲线 drawOneBezier(canvas); } //绘制一阶曲线 private void drawOneBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,50); //路径终点 mPath.lineTo(100,150); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); } }二.绘制二阶和三阶
1.二阶: mPath.quadTo(twoControlX,twoControlY,100,150);
2.三阶:mPath.cubicTo(threeControlX1,threeControlY1, threeControlX2, threeControlY2, 500, 500);
public class BezierView extends View { private Path mPath;//路径 private Paint mPaint;//画笔 //二阶曲线的控制点 public float twoControlX = 50; public float twoControlY = 50; //三阶曲线的控制点 public float threeControlX1 = 200; public float threeControlY1 = 300; public float threeControlX2 = 400; public float threeControlY2 = 300; //java代码 public BezierView(Context context) { super(context); initPaint(); } //xml布局 public BezierView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initPaint(); } public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } private void initPaint() { //画笔 mPaint = new Paint(); //设置样式 STROKE:空心 FILL:实心 mPaint.setStyle(Paint.Style.STROKE); //设置宽度 mPaint.setStrokeWidth(20); //抗锯齿 mPaint.setAntiAlias(true); //防抖动 mPaint.setDither(true); //路径 mPath = new Path(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制一阶曲线 drawOneBezier(canvas); //绘制二阶曲线 drawTwoBezier(canvas); //绘制三阶曲线 drawThreeBezier(canvas); } //绘制三阶曲线 private void drawThreeBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,250); //绘制3阶 mPath.cubicTo(threeControlX1,threeControlY1, threeControlX2, threeControlY2, 500, 500); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); } //绘制二阶曲线 private void drawTwoBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,250); //绘制2阶 1:控制点X 2:控制点Y 3:终点X 4:终点的Y mPath.quadTo(twoControlX,twoControlY,100,150); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); } //绘制一阶曲线 private void drawOneBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,50); //路径终点 mPath.lineTo(100,150); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); } }三.绘制辅助线和控制点
//绘制二阶曲线 private void drawTwoBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,250); //绘制2阶 1:控制点X 2:控制点Y 3:终点X 4:终点的Y mPath.quadTo(twoControlX,twoControlY,500,250); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); //---辅助线--- //设置画笔的颜色 mPaint.setColor(Color.YELLOW); //通过path对象移动到起点位置 mPath.moveTo(50, 250); //画一个从起点到控制点的线 mPath.lineTo( twoControlX, twoControlY); //从控制点到终点的线 mPath.lineTo(500, 250); //绘制路径 canvas.drawPath(mPath, mPaint); //重置路径 mPath.reset(); //---画出控制的点--- //设置画笔的颜色 mPaint.setColor(Color.GREEN); //画一个控制点的圆 圆心是控制点的X和Y 半径是10 canvas.drawCircle( twoControlX, twoControlY, 10, mPaint); //重置路径 mPath.reset(); }
//绘制三阶曲线 private void drawThreeBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,500); //绘制3阶 mPath.cubicTo(threeControlX1,threeControlY1, threeControlX2, threeControlY2, 500, 500); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); //---辅助线--- mPaint.setColor(Color.YELLOW); //通过path对象移动到起点位置 mPath.moveTo(50, 500); //从起点画到第一个控制点 mPath.lineTo( threeControlX1, threeControlY1); //从第一个控制点画到第二个控制点 mPath.lineTo( threeControlX2, threeControlY2); //从第二个控制点画到终点 mPath.lineTo(500, 500); //绘制路径 canvas.drawPath(mPath, mPaint); //重置路径 mPath.reset(); //---画出控制的点--- mPaint.setColor(Color.GREEN); //画二个控制点的圆 圆心是控制点的X和Y 半径是10 canvas.drawCircle( threeControlX1, threeControlY1, 10, mPaint); canvas.drawCircle( threeControlX2, threeControlY2, 10, mPaint); }四.勾股定理:碰撞测试 1.碰撞测试
//判断手指的触点是否在圆内,碰撞判断 private boolean isChekCircle(PointF pointF, PointF circle, float radius) { return Math.pow((pointF.x - circle.x),2)+Math.pow((pointF.y-circle.y),2)<= Math.pow(radius,2); }2.事件处理
//消费后做处理 getAction Down Move Up @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { //当手指按下得时候 case MotionEvent.ACTION_DOWN: //判断二阶得点有没有被点击到 boolean twoControl = isChekCircle(new PointF(event.getX(), event.getY()), new PointF((float) twoControlX, (float) twoControlY), 50); //判断三阶得点有没有被点击到 boolean threeControl1 = isChekCircle(new PointF(event.getX(), event.getY()), new PointF((float) threeControlX1, (float) threeControlY1), 50); boolean threeControl2 = isChekCircle(new PointF(event.getX(), event.getY()), new PointF((float) threeControlX2, (float) threeControlY2), 50); if (twoControl) { mType = 0; } else if (threeControl1) { mType = 1; } else if (threeControl2) { mType = 2; } else { mType = -1; } break; //当手指移动得时候 case MotionEvent.ACTION_MOVE: //将当前得点赋值给二阶贝塞尔曲线得控制点 if (mType == 0) { twoControlX = event.getX(); twoControlY = event.getY(); invalidate(); //将当前得点赋值给三阶贝塞尔曲线得控制点1 } else if (mType == 1) { threeControlX1 = event.getX(); threeControlY1 = event.getY(); invalidate(); // 将当前得点赋值给三阶贝塞尔曲线得控制点2 } else if (mType == 2) { threeControlX2 = event.getX(); threeControlY2 = event.getY(); invalidate(); } break; case MotionEvent.ACTION_UP: break; } return true; }3.全部代码
public class BezierView extends View { private Path mPath;//路径 private Paint mPaint;//画笔 //二阶曲线的控制点 public float twoControlX = 50; public float twoControlY = 50; //三阶曲线的控制点 public float threeControlX1 = 200; public float threeControlY1 = 300; public float threeControlX2 = 400; public float threeControlY2 = 300; //判断碰撞 private int mType; //java代码 public BezierView(Context context) { super(context); initPaint(); } //xml布局 public BezierView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initPaint(); } public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public BezierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } private void initPaint() { //画笔 mPaint = new Paint(); //设置样式 STROKE:空心 FILL:实心 mPaint.setStyle(Paint.Style.STROKE); //设置宽度 mPaint.setStrokeWidth(20); //抗锯齿 mPaint.setAntiAlias(true); //防抖动 mPaint.setDither(true); //路径 mPath = new Path(); } //测量View的大小 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //单独测量宽高 int w = measureSingle(widthMeasureSpec); int h = measureSingle(heightMeasureSpec); //设置宽高 setMeasuredDimension(w, h); } //单独测量 private int measureSingle(int measureSpec) { int result = 0; //测量模式 int mode = MeasureSpec.getMode(measureSpec); //测量大小 int size = MeasureSpec.getSize(measureSpec); //当是无限模式 返回200 if (mode == MeasureSpec.AT_MOST) {//当WRAP result = 500; } else { result = size; } return result; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制一阶曲线 drawOneBezier(canvas); //绘制二阶曲线 drawTwoBezier(canvas); //绘制三阶曲线 drawThreeBezier(canvas); } //绘制三阶曲线 private void drawThreeBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,500); //绘制3阶 mPath.cubicTo(threeControlX1,threeControlY1, threeControlX2, threeControlY2, 500, 500); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); //---辅助线--- mPaint.setColor(Color.YELLOW); //通过path对象移动到起点位置 mPath.moveTo(50, 500); //从起点画到第一个控制点 mPath.lineTo( threeControlX1, threeControlY1); //从第一个控制点画到第二个控制点 mPath.lineTo( threeControlX2, threeControlY2); //从第二个控制点画到终点 mPath.lineTo(500, 500); //绘制路径 canvas.drawPath(mPath, mPaint); //重置路径 mPath.reset(); //---画出控制的点--- mPaint.setColor(Color.GREEN); //画二个控制点的圆 圆心是控制点的X和Y 半径是10 canvas.drawCircle( threeControlX1, threeControlY1, 10, mPaint); canvas.drawCircle( threeControlX2, threeControlY2, 10, mPaint); } //绘制二阶曲线 private void drawTwoBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,250); //绘制2阶 1:控制点X 2:控制点Y 3:终点X 4:终点的Y mPath.quadTo(twoControlX,twoControlY,500,250); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); //---辅助线--- //设置画笔的颜色 mPaint.setColor(Color.YELLOW); //通过path对象移动到起点位置 mPath.moveTo(50, 250); //画一个从起点到控制点的线 mPath.lineTo( twoControlX, twoControlY); //从控制点到终点的线 mPath.lineTo(500, 250); //绘制路径 canvas.drawPath(mPath, mPaint); //重置路径 mPath.reset(); //---画出控制的点--- //设置画笔的颜色 mPaint.setColor(Color.GREEN); //画一个控制点的圆 圆心是控制点的X和Y 半径是10 canvas.drawCircle( twoControlX, twoControlY, 10, mPaint); //重置路径 mPath.reset(); } //绘制一阶曲线 private void drawOneBezier(Canvas canvas) { //设置画笔颜色 mPaint.setColor(Color.RED); //路径起点 mPath.moveTo(50,50); //路径终点 mPath.lineTo(100,150); //绘制路径 canvas.drawPath(mPath,mPaint); //重置路径 mPath.reset(); } //生成一个事务 @Override public boolean dispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); } //消费后做处理 getAction Down Move Up @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { //当手指按下得时候 case MotionEvent.ACTION_DOWN: //判断二阶得点有没有被点击到 boolean twoControl = isChekCircle(new PointF(event.getX(), event.getY()), new PointF((float) twoControlX, (float) twoControlY), 50); //判断三阶得点有没有被点击到 boolean threeControl1 = isChekCircle(new PointF(event.getX(), event.getY()), new PointF((float) threeControlX1, (float) threeControlY1), 50); boolean threeControl2 = isChekCircle(new PointF(event.getX(), event.getY()), new PointF((float) threeControlX2, (float) threeControlY2), 50); if (twoControl) { mType = 0; } else if (threeControl1) { mType = 1; } else if (threeControl2) { mType = 2; } else { mType = -1; } break; //当手指移动得时候 case MotionEvent.ACTION_MOVE: //将当前得点赋值给二阶贝塞尔曲线得控制点 if (mType == 0) { twoControlX = event.getX(); twoControlY = event.getY(); invalidate(); //将当前得点赋值给三阶贝塞尔曲线得控制点1 } else if (mType == 1) { threeControlX1 = event.getX(); threeControlY1 = event.getY(); invalidate(); // 将当前得点赋值给三阶贝塞尔曲线得控制点2 } else if (mType == 2) { threeControlX2 = event.getX(); threeControlY2 = event.getY(); invalidate(); } break; case MotionEvent.ACTION_UP: break; } return true; } //判断手指的触点是否在圆内,碰撞判断 private boolean isChekCircle(PointF pointF, PointF circle, float radius) { return Math.sqrt(Math.pow((pointF.x - circle.x), 2) + Math.pow((pointF.y - circle.y), 2)) <= radius; } }