android:贝塞尔曲线简单实现
2016-06-27 17:00
417 查看
原理图:
看了半天网上的讲解,我也不是很懂,上面的公式 ,大概让我知道了些,原来这平滑的曲线,是用这公式得出的。不研究里面具体的算法了,下面说下在安卓上怎么实现。感谢http://weibo.com/GcsSloop?is_hot=1,我从这里获取的资料。
1.二阶贝塞尔曲线绘制
谷歌封装了一个方法quadTo,给出起点,控制点以及终点,就可以直接绘制二阶贝塞尔取消,demo如下
2.三阶贝塞尔曲线绘制
谷歌封装了一个方法cubicTo,给出起点,控制点以及终点,就可以直接绘制三阶贝塞尔取消,demo如下
看了半天网上的讲解,我也不是很懂,上面的公式 ,大概让我知道了些,原来这平滑的曲线,是用这公式得出的。不研究里面具体的算法了,下面说下在安卓上怎么实现。感谢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); } }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories