android中贝塞尔曲线的应用示例-创新互联

前言:

成都创新互联主要从事成都网站建设、网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务新乡县,十载网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575

贝塞尔曲线又称贝兹曲线,它的主要意义在于无论是直线或曲线都能在数学上予以描述。最初由保罗·德卡斯特里奥(Paul de Casteljau)于1959年运用德卡斯特里奥演算法开发(de Casteljau Algorithm),在1962,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表。目前广泛应用于图形绘制领域来模拟光滑曲线,为计算机矢量图形学奠定了基础。在一些图形处理软件中都能见到贝塞尔曲线,比如CorelDraw中翻译成“贝赛尔工具”;而在Fireworks中叫“画笔”;Photoshop中叫“钢笔工具”。下图为Photoshop中用钢笔绘制的贝塞尔曲线,共绘制了三条贝塞尔曲线:

android中贝塞尔曲线的应用示例


数学表达

术语:数据点、控制线、控制点、德卡斯特里奥算法、一阶,二阶,三阶,n阶……

  1. 数据点:一条贝塞尔曲线的起始点和终结点都叫数据点。
  2. 控制线:在图中可以看到那条中心点为数据点的线段,每个数据点对应一条控制线
  3. 控制点:就是控制线的端点,通过控制线随着控制点的变化而变化;数据点和控制点决定一条贝塞尔曲线。
  4. 一阶贝塞尔曲线:其实是一条直线段,没有控制点。

一阶贝塞尔曲线示意图

android中贝塞尔曲线的应用示例


一阶贝塞尔曲线公式android中贝塞尔曲线的应用示例


二阶贝塞尔曲线:图中第二段为二阶贝塞尔曲线,只有一个控制点,即只有一个控制点和两个数据点来决定曲线形状。

android中贝塞尔曲线的应用示例

二阶贝塞尔曲线公式android中贝塞尔曲线的应用示例

二阶公式推导:

android中贝塞尔曲线的应用示例
二阶贝塞尔曲线t=0.6示意图.gif
根据控制点和数据点,对贝塞尔曲线进行约束,满足的条件为

android中贝塞尔曲线的应用示例


问题变为:已知P0(x0,y0), P1(x1,y1), P2(x2,y2),根据上式求P点坐标?


先求出A、B点坐标,其坐标


PA=P0+(P1-P0)·t


PB=P1+(P2-P1)·t


之后求P点坐标,其坐标


P=PA+(PB-PA)·t


P=(1-t)2P0+2t(1-t)P1+t2P2, t∈[0,1]

三阶贝塞尔曲线:图中第三段为三阶贝塞尔曲线,有两个控制点和两个数据点决定的曲线,同样满足等比条件:

android中贝塞尔曲线的应用示例

三阶贝塞尔曲线

三阶贝塞尔曲线公式android中贝塞尔曲线的应用示例


德卡斯特里奥算法的思想:给定数据点和控制点P0、P1…Pn,首先将数据点和控制点连接形成一条折线,计算出每条折线上面的一点,使得初始数据点(初始控制点)到该点的距离与初始数据点(初始控制点)到终止数据点(终止控制点)的距离之比为t:1。将这些点连接起来形成新的折线(折线少了一段),用递归的算法继续计算,指导只有两个点,在这两个点形成的线段上去一点,满足以上的比例关系。随着t的从0到1的变化,该点的集合形成了贝塞尔曲线。

n阶贝塞尔曲线公式如下。

android中贝塞尔曲线的应用示例


Android中的应用

对android中如何获取贝塞尔曲线上的点,如何绘制贝塞尔曲线,以及结合贝塞尔曲线的知识做出的效果进行分析。

1. 获取贝塞尔曲线上点的坐标

在android中并没有直接获取的方法,因此需要利用上面的公式进行计算,以二阶贝塞尔曲线为例,获取51个点,主要是t从0开始到1间取51项的等差数列:

public class MainActivity extends AppCompatActivity {

  private static final float mPointNum = 50f;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    init();
  }

  private void init() {
    PointF mStartPoint = new PointF(0, 0);
    PointF mEndPoint = new PointF(0, 1200);
    PointF mControlPoint = new PointF(500, 600);

    List mPointList = new ArrayList<>();
    for (int i = 0; i <= mPointNum; i++) {
      mPointList.add(getBezierPoint(mStartPoint, mEndPoint, mControlPoint, i / mPointNum));
      Log.d("Bezier", "X:" + mPointList.get(i).x + " Y:" + mPointList.get(i).y);
    }
  }

  private PointF getBezierPoint(PointF start, PointF end, PointF control, float t) {
    PointF bezierPoint = new PointF();
    bezierPoint.x = (1 - t) * (1 - t) * start.x + 2 * t * (1 - t) * control.x + t * t * end.x;
    bezierPoint.y = (1 - t) * (1 - t) * start.y + 2 * t * (1 - t) * control.y + t * t * end.y;
    return bezierPoint;
  }
}


新闻标题:android中贝塞尔曲线的应用示例-创新互联
分享网址:http://myzitong.com/article/cooeij.html