首页 > 系统 > Android > 正文

Android中贝塞尔曲线的绘制方法示例代码

2019-12-12 05:35:11
字体:
来源:转载
供稿:网友

       贝塞尔曲线,很多人可能不太了解,什么叫做贝塞尔曲线呢?这里先做一下简单介绍:贝塞尔曲线也可以叫做贝济埃曲线或者贝兹曲线,它由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋。一般的矢量图形软件常利用贝塞尔曲线来精确画出曲线。

       上面的介绍中,“线段像可伸缩的皮筋”这句话非常关键,但也特别好理解。至于贝塞尔曲线的详细内容大家可以查阅相关资料。

       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 贝塞尔曲线的绘制的示例代码,后续继续补充相关知识,谢谢大家对本站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表