贝塞尔曲线,很多人可能不太了解,什么叫做贝塞尔曲线呢?这里先做一下简单介绍:贝塞尔曲线也可以叫做贝济埃曲线或者贝兹曲线,它由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋。一般的矢量图形软件常利用贝塞尔曲线来精确画出曲线。
上面的介绍中,“线段像可伸缩的皮筋”这句话非常关键,但也特别好理解。至于贝塞尔曲线的详细内容大家可以查阅相关资料。
Android提供的贝塞尔曲线绘制接口
在Android开发中,要实现贝塞尔曲线其实还是很简单的,因为Android已经给我们提供了相关接口,但此接口方法被藏的有点深,藏于Path类中。此方法如下:
android.graphics.Path.quadTo(float x1, float y1, float x2, float y2)
Since: API Level 1
参数说明:
x1:操作点的x坐标
y1:操作点的y坐标
x2:结束点的x坐标
y2:结束点的y坐标
从API中看出,贝塞尔曲线从API-1就开始支持了。
Android贝塞尔曲线的绘制实例
熟悉方法后,下面就来实现:
SurfaceView框架不多讲,看过我博客的都应该知道的。
直接看MySurfaceView类,此类继承SurfaceView,是游戏的主视图。
这里为了更清晰的讲解:这里部分代码先不贴出来了,最后会整体贴出。
首先是定义相关的成员变量:
Java代码
// 贝赛尔曲线成员变量(起始点,控制(操作点),终止点,3点坐标)
private int startX, startY, controlX, controlY, endX, endY;
// Path
private Path path;
// 为了不影响主画笔,这里绘制贝赛尔曲线单独用一个新画笔
private Paint paintQ;
// 随机库(让贝赛尔曲线更明显)
private Random random;
本类构造函数:
Java代码
/**
* SurfaceView初始化函数
*/
public MySurfaceView(Context context) {
super(context);
...
//贝赛尔曲线相关初始化
path = new Path();
paintQ = new Paint();
paintQ.setAntiAlias(true);
paintQ.setStyle(Style.STROKE);
paintQ.setStrokeWidth(5);
paintQ.setColor(Color.WHITE);
random = new Random();
...
}
接着我把贝赛尔曲线的绘制封装成一个方法了,函数如下:
Java代码
/**
* 绘制贝赛尔曲线
*
* @param canvas 主画布
*/
public void drawQpath(Canvas canvas) {
path.reset();// 重置path
// 贝赛尔曲线的起始点
path.moveTo(startX, startY);
// 设置贝赛尔曲线的操作点以及终止点
path.quadTo(controlX, controlY, endX, endY);
// 绘制贝赛尔曲线(Path)
canvas.drawPath(path, paintQ);
}
最后是用户触屏监听函数以及逻辑函数:
Java代码
/**
* 触屏事件监听
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
endX = (int) event.getX();
endY = (int) event.getY();
return true;
}
/**
* 游戏逻辑
*/
private void logic() {
if (endX != 0 && endY != 0) {
// 设置操作点为线段x/y的一半
controlX = random.nextInt((endX - startX) / 2);
controlY = random.nextInt((endY - startY) / 2);
}
}
整个代码很easy,主要是贝赛尔函数的参数,尤其是操作点,操作点的各种不同可以实现不同的效果,这里我简单的统一的讲操作点设置成用户触屏点的x、y的一半,呵呵偷懒了~~
我把贝赛尔的操作点写在了逻辑logic()函数中,不断的执行,并且每次利用nextInt函数得到随机的操作点,主要为了让其曲线不断的变化从而形成一个震动的曲线运动轨迹。
运行效果截图如下:
这里可能由于图片是静止的,所以效果看起来不是很明显,大家可以运行源码来观察。
下面贴出整个MySurfaceView的源码:
Java代码
package com.qpath;
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
/**
* 赛贝尔曲线
* @author Himi
*
*/
public class MySurfaceView extends SurfaceView implements Callback, Runnable {
private SurfaceHolder sfh;
private Paint paint;
private Thread th;
private boolean flag;
private Canvas canvas;
public static int screenW, screenH;
// -----------以上是SurfaceView游戏框架
// 贝赛尔曲线成员变量(起始点,控制(操作点),终止点,3点坐标)
private int startX, startY, controlX, controlY, endX, endY;
// Path
private Path path;
// 为了不影响主画笔,这里绘制贝赛尔曲线单独用一个新画笔
private Paint paintQ;
// 随机库(让贝赛尔曲线更明显)
private Random random;
/**
* SurfaceView初始化函数
*/
public MySurfaceView(Context context) {
super(context);
sfh = this.getHolder();
sfh.addCallback(this);
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
setFocusable(true);
// -----------以上是SurfaceView游戏框架
//贝赛尔曲线相关初始化
path = new Path();
paintQ = new Paint();
paintQ.setAntiAlias(true);
paintQ.setStyle(Style.STROKE);
paintQ.setStrokeWidth(5);
paintQ.setColor(Color.WHITE);
random = new Random();
}
/**
* SurfaceView视图创建,响应此函数
*/
public void surfaceCreated(SurfaceHolder holder) {
screenW = this.getWidth();
screenH = this.getHeight();
flag = true;
// 实例线程
th = new Thread(this);
// 启动线程
th.start();
// -----------以上是SurfaceView游戏框架
}
/**
* 游戏绘图
*/
public void myDraw() {
try {
canvas = sfh.lockCanvas();
if (canvas != null) {
canvas.drawColor(Color.BLACK);
// -----------以上是SurfaceView游戏框架
drawQpath(canvas);
}
} catch (Exception e) {
// TODO: handle exception
} finally {
if (canvas != null)
sfh.unlockCanvasAndPost(canvas);
}
}
/**
* 绘制贝赛尔曲线
*
* @param canvas 主画布
*/
public void drawQpath(Canvas canvas) {
path.reset();// 重置path
// 贝赛尔曲线的起始点
path.moveTo(startX, startY);
// 设置贝赛尔曲线的操作点以及终止点
path.quadTo(controlX, controlY, endX, endY);
// 绘制贝赛尔曲线(Path)
canvas.drawPath(path, paintQ);
}
/**
* 触屏事件监听
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
endX = (int) event.getX();
endY = (int) event.getY();
return true;
}
/**
* 游戏逻辑
*/
private void logic() {
if (endX != 0 && endY != 0) {
// 设置操作点为线段x/y的一半
controlX = random.nextInt((endX - startX) / 2);
controlY = random.nextInt((endY - startY) / 2);
}
}
/**
* 按键事件监听
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event);
}
public void run() {
while (flag) {
long start = System.currentTimeMillis();
myDraw();
logic();
long end = System.currentTimeMillis();
try {
if (end - start < 50) {
Thread.sleep(50 - (end - start));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* SurfaceView视图状态发生改变,响应此函数
*/
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
/**
* SurfaceView视图消亡时,响应此函数
*/
public void surfaceDestroyed(SurfaceHolder holder) {
flag = false;
}
}
以上就是对Android 贝塞尔曲线的绘制的示例代码,后续继续补充相关知识,谢谢大家对本站的支持!
您可能感兴趣的文章:Android把商品添加到购物车的动画效果(贝塞尔曲线)android中贝塞尔曲线的应用示例Android 利用三阶贝塞尔曲线绘制运动轨迹的示例Android贝塞尔曲线初步学习第三课 Android实现添加至购物车的运动轨迹Android贝塞尔曲线初步学习第一课Android贝塞尔曲线实现手指轨迹Android贝塞尔曲线实现填充不规则图形并随手指运动Android使用贝塞尔曲线仿QQ聊天消息气泡拖拽效果Android贝塞尔曲线实现消息拖拽消失android贝塞尔曲线实现波浪效果