您的位置:首页 > 移动开发 > Android开发

android:贝塞尔曲线简单实现

2016-06-27 17:00 417 查看
原理图:



看了半天网上的讲解,我也不是很懂,上面的公式 ,大概让我知道了些,原来这平滑的曲线,是用这公式得出的。不研究里面具体的算法了,下面说下在安卓上怎么实现。感谢http://weibo.com/GcsSloop?is_hot=1,我从这里获取的资料。

1.二阶贝塞尔曲线绘制

谷歌封装了一个方法quadTo,给出起点,控制点以及终点,就可以直接绘制二阶贝塞尔取消,demo如下

package com.wx.beziermaker;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.View;

/**
* Created by huqing on 2016/6/27.
*/
public class TwoBezier extends View {
private Paint mPaint;
private int centerX, centerY;
private PointF start, end, fingerPoint;

/**
*     使用,例:
*    TwoBezier mBezier = new TwoBezier(this);
*    setContentView(mBezier);
*
* @param context
*/
public TwoBezier(Context context) {
super(context);
//画笔
mPaint = new Paint();
mPaint.setStrokeWidth(8);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setTextSize(60);
//三点确定该二阶曲线
start = new PointF(0, 0);
end = new PointF(0, 0);
fingerPoint = new PointF(0, 0);
}

/**
* 手指触碰时获取当前手指坐标
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// 根据触摸位置更新控制点,并提示重绘
fingerPoint.x = event.getX();
fingerPoint.y = event.getY();
invalidate();//调用onDraw方法
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(fingerPoint.x, fingerPoint.y, mPaint);
// 绘制辅助线
mPaint.setStrokeWidth(4);
canvas.drawLine(start.x, start.y, fingerPoint.x, fingerPoint.y, mPaint);
canvas.drawLine(end.x, end.y, fingerPoint.x, fingerPoint.y, mPaint);
// 绘制贝塞尔曲线
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(8);
//绘制曲线路径
Path path = new Path();
//起点
path.moveTo(start.x, start.y);
//关键方法:谷歌封装好的贝塞尔曲线绘制方法quadTo,给出控制点和终点
path.quadTo(fingerPoint.x, fingerPoint.y, end.x, end.y);
canvas.drawPath(path, mPaint);
}

/**
* onSizeChanged的启动时间在onDraw之前,初始化该View时获取到长宽
*/
@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;
//控制点,就是手指移动的那个点
fingerPoint.x = centerX;
fingerPoint.y = centerY - 100;
}
}


2.三阶贝塞尔曲线绘制

谷歌封装了一个方法cubicTo,给出起点,控制点以及终点,就可以直接绘制三阶贝塞尔取消,demo如下

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
* Created by huqing on 2016/6/27.
*/
public class BezierThree extends View {

private Paint mPaint;
private int centerX, centerY;
private PointF start, end, fingerPointOne, fingerPointTwo;
private boolean mode = true;

public BezierThree(Context context) {
this(context, null);
}

public BezierThree(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);
fingerPointOne = new PointF(0, 0);
fingerPointTwo = 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 = 10;
start.y = centerY;
end.x = w - 10;
end.y = centerY;
fingerPointOne.x = centerX;
fingerPointOne.y = centerY - 100;
fingerPointTwo.x = centerX;
fingerPointTwo.y = centerY - 100;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// 根据触摸位置更新控制点,并提示重绘
if (mode) {
fingerPointOne.x = event.getX();
fingerPointOne.y = event.getY();
} else {
fingerPointTwo.x = event.getX();
fingerPointTwo.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(fingerPointOne.x, fingerPointOne.y, mPaint);
//        canvas.drawPoint(fingerPointTwo.x, fingerPointTwo.y, mPaint);
//        // 绘制辅助线
//        mPaint.setStrokeWidth(4);
//        canvas.drawLine(start.x, start.y, fingerPointOne.x, fingerPointOne.y, mPaint);
//        canvas.drawLine(fingerPointOne.x, fingerPointOne.y, fingerPointTwo.x, fingerPointTwo.y, mPaint);
//        canvas.drawLine(fingerPointTwo.x, fingerPointTwo.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(fingerPointOne.x, fingerPointOne.y, fingerPointTwo.x, fingerPointTwo.y, end.x, end.y);
canvas.drawPath(path, mPaint);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android