【转】贝塞尔曲线介绍

原文链接:

http://blog.csdn.net/sangxiaonian/article/details/51984013

http://blog.csdn.net/sangxiaonian/article/details/51984584

http://blog.csdn.net/sangxiaonian/article/details/51985405

其他参考链接:

https://www.jianshu.com/p/55c721887568

作为一个有只志向的码农,除了知道一些基本的知识够自己努力搬砖以外,还应该get一些更炫酷的技能,用更优雅的姿势进行搬砖;想要实现一些十分炫酷的效果,贝塞尔曲线就必须进行一些研究了; 
最近一段时间,我对贝塞尔曲线进行了部分的研究,因此就打算写贝塞尔曲线系列的文章来记录自己的研究;

规矩我都懂 !

??我明白,必须先上图,要不然大家都没兴趣看下去

先看比较简单的,贝塞尔曲线的一阶和二阶的应用

??看到二阶的贝塞尔曲线有没有感觉很眼熟,没错,360的下火箭弹射时候的小弹弓,还有滑动控件的阴影提示;以前的时候很多小伙伴跟我说这要计算多少数据啊,完全没办法实现啊,现在有了贝塞尔曲线,可以很简单的实现这一个功能; 
??不过完全不能这样满足啊,接下来还有更复杂一些的曲线

??没错,这个就是三阶的使用,有没有感觉路线更加复杂,不过还好,使用贝塞尔去玩完全可以轻松实现;对了,还有一个心在沿着曲线移动,看到这里,小伙伴们肯定会想到满屏幕的心在飞的场景,放心,这个我也实现了,在接下来的文章里,我会一一进行讲解;

图片看完了,现在简单了解贝塞尔曲线

Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。

以下公式中:B(t)为t时间下 点的坐标;

P0为起点,Pn为终点,Pi为控制点

一阶贝塞尔曲线(线段):

意义:由 P0 至 P1 的连续点, 描述的一条线段

二阶贝塞尔曲线(抛物线):

原理:由 P0 至 P1 的连续点 Q0,描述一条线段。 
由 P1 至 P2 的连续点 Q1,描述一条线段。 
由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。

经验:P1-P0为曲线在P0处的切线。

三阶贝塞尔曲线:

通用公式:

利用贝塞尔曲线的这些特性,我们可以画出很多炫酷的曲线,所以贝塞尔曲线还是值得我们去研究学习的;

但是这些完全记不住啊!!!

没关系,可以很负责的说,我也是!!!!!

上面的曲线完全是来自http://blog.csdn.net/tianhai110/article/details/2203572

所以,如果你的数学和我一样是体育老师教的,就忘记这些吧,跟我一起看看android中是实现一条贝塞尔曲线的,android已经帮我们实现好了,剩下的就需要我们进行简单使用,具体的使用,就看下一篇中讲解

最后附上源码:https://github.com/sangxiaonian/BezierIntroduce.git

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

上一篇中我简单的介(粘)绍(贴)了一下贝塞尔曲线(Bezier)曲线的原理和公式,但是作为数学界排的上名号的渣渣,我只能默默的溜过; 
?? 不过还好,android帮我们实现好了这个贝塞尔曲线的使用;

Path

??这个类中封装了要使用贝塞尔曲线(Bezier)的简单方法;使用起来也很简单,总的来说也只有三步

  • 初始化Path
 mPath = new Path();

  

  • path移动到起点
  mPath.moveTo(startX, startY / 3);

  

  • 确定直线的终点
 mPath.lineTo(endX, endY / 3);
  • 调用canvas绘制贝塞尔曲线
 canvas.drawPath(mPath, mPaint);

  

??好了,到这里一阶的一条直线就完成了; 
??但是这个完全没任何卵用啊,就一条直线有木有!!

??但是,我们可以一直画下去,就像这样:

      path.moveTo(touchX + getWidth() / 20, touchY - getHeight() / 10);
        path.lineTo(touchX + getWidth() / 20, touchY);
        path.lineTo(touchX - getWidth() / 20, touchY);
        path.lineTo(touchX - getWidth() / 20, touchY - getHeight() / 10);
        path.lineTo(touchX, touchY - getHeight() / 7);
        path.lineTo(touchX + getWidth() / 20, touchY - getHeight() / 10 + 2);

  这段代码绘制完成之后就是一个随着手指一动的小火箭了

 
??丑爆了有木有,不过还好,如果是大神的话应该可以绘制成一个比较好一些的了吧,主要还是原理,相对于自己直接画直线,已经大大简化了;

二阶曲线

??二阶曲线在安卓中的定义也是很简单的,就是调用quadTo方法,

        mPath.moveTo(startX, startY);
        mPath.quadTo(touchX, touchY, endX, endY);
        canvas.drawPath(mPath, mPaint);

  

 

不管是几阶的,都是要先moveTo到起点;

三阶曲线 ##

         mPath.moveTo(pointFStart.x, pointFStart.y);
        mPath.cubicTo(pointFFirst.x, pointFFirst.y, pointFSecond.x, pointFSecond.y, pointFEnd.x, pointFEnd.y);
        canvas.drawPath(mPath, mPaint);

  途中从下倒上,四个点依次是pointFStart,pointFFirst,pointFSecond,pointFSecond;根本没什么难度,非常简单,可以直接使用,上篇提到的”心”的移动就是按照这个轨迹进行移动,所以看起来十分顺滑,效果也不错;

贝塞尔曲线的绘制本身并没有什么难度,这些都是很基础的一些东西,但是却能实现一些很炫酷的效果,比如qq上的粘性控件的效果等,这些都可以实现;

好了,简单的使用就介绍到这里了,下一篇我会利用贝塞尔曲线实现一些炫酷的效果

最后附上源码:https://github.com/sangxiaonian/BezierIntroduce.git

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

这一篇文章会完整的介绍如何通过贝塞尔曲线实现爱心点赞的效果,如果实在看不懂,可以看第一篇贝塞尔曲线的简介,还有第二篇安卓中的简单使用;

好了,终于到了放大招的时候了,真实憋了很久了 
 
先做一些准备工作,绘制各种颜色的红心:

  private Bitmap creatHeart(int color) {

   int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Bitmap newBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(newBitmap);
        canvas.drawBitmap(bitmap, 0, 0, criPaint);
        canvas.drawColor(color, PorterDuff.Mode.SRC_ATOP);
        canvas.setBitmap(null);
        return newBitmap;
}

  

这里面比较关键的代码只有是 canvas.drawColor(color, PorterDuff.Mode.SRC_ATOP),关于PorterDuff,还是可以去学习了解一下的,很多时候还是很有用的,在这里简单的介绍一下; 

这样就比较清晰明了了吧,这里使用的就是SRC_ATOP,去心的图形和颜色重叠部分,就是心了; 
这样只要准备一个心形图片,就能实现格式各样的心了;

接下来就是进行根据轨迹进行绘制了,看过第一篇文章的,就应该根据几个点,就能绘制出来一条轨迹;这里使用属性动画,来获取相对应的轨迹;

首先

 /**
     * 绘制一个增值器
     */
    class TypeE implements TypeEvaluator<PointF> {

        private PointF pointFFirst,pointFSecond;

        public TypeE(PointF start,PointF end){
            this.pointFFirst =start;
            this.pointFSecond = end;
        }

        @Override
        public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
            PointF result = new PointF();
            float left = 1 - fraction;
            result.x = (float) (startValue.x*Math.pow(left,3)+3*pointFFirst.x*Math.pow(left,2)*fraction+3*pointFSecond.x*Math.pow(fraction, 2)*left+endValue.x*Math.pow(fraction,3));
            result.y= (float) (startValue.y*Math.pow(left,3)+3*pointFFirst.y*Math.pow(left,2)*fraction+3*pointFSecond.y*Math.pow(fraction, 2)*left+endValue.y*Math.pow(fraction,3));
            return result;
        }
    }

  

 

这个很简单,就是单纯的使用公式了,所以说想要绘制复杂的轨迹,我还是要重新拾起来被扔进粪坑的小学数学课本重新看看,当真是熏得泪流满面啊!! 
接下来就很简单了,只要不停使用属性动画,不断变换位置就好了;

private void moveHeart(final ImageView view){
        PointF pointFFirst = this.pointFFirst;
        PointF pointFSecond = this.pointFSecond;
        PointF pointFStart = this.pointFStart;
        PointF pointFEnd = this.pointFEnd;

        ValueAnimator animator = ValueAnimator.ofObject(new TypeE(pointFFirst, pointFSecond), pointFStart, pointFEnd);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF value = (PointF) animation.getAnimatedValue();
                view.setX(value.x);
                view.setY(value.y);
            }
        });

        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                AdvancePathView.this.removeView(view);
            }
        });

        ObjectAnimator af = ObjectAnimator.ofFloat(view, "alpha", 1f, 0);
        af.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                AdvancePathView.this.removeView(view);
            }
        });

       AnimatorSet set = new AnimatorSet();
        set.setDuration(3000);
        set.play(animator).with(af);
        set.start();

    }

  

就是这么简单,完全没有难度啊有木有!!! 
总的来说还是三步: 
第一

  1. :绘制各种颜色的心
  2. 绘制一个增值器,获取轨迹
  3. 使用属性动画,根据轨迹移动位置

好了,到这里我这一系列的文章就结束了,两天水时间搞的,感觉稍微有点水,但是就这样啦,毕竟本身不是很难的东西,有什么问题可以问我,有时间一定会耐心解答的;

最后附上源码:https://github.com/sangxiaonian/BezierIntroduce.git

原文地址:https://www.cnblogs.com/ryq2014/p/8432318.html

时间: 2024-10-10 13:21:36

【转】贝塞尔曲线介绍的相关文章

贝塞尔曲线介绍及一阶、二阶推导

贝塞尔曲线介绍及一阶.二阶推导 https://blog.csdn.net/qq_34501940/article/details/80451872 贝塞尔曲线介绍及一阶.二阶推导原创IT_Faith 最后发布于2018-05-25 14:59:54 阅读数 2954 收藏展开简介说明贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,当时主要用于汽车主体设计. 通过比例进行不断地取点,点不断地汇成一条平滑的曲线.

iOS:使用贝塞尔曲线绘制图表(折线图、柱状图、饼状图)

1.介绍: UIBezierPath :画贝塞尔曲线的path类 UIBezierPath定义 : 贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度. 曲线的定义有四个点:起始点.终止点(也称锚点)以及两个相互分离的中间点. 滑动两个中间点,贝塞尔曲线的形状会发生变化. UIBezierPath :对象是CGPathRef数据类型的封装,可以方便的让我们画出 矩形 . 椭圆 或者 直线和曲线的组合形状 初始化方法: + (instancetype)bezierPath; /

【开源项目解析】QQ“一键下班”功能实现解析——学习Path及贝塞尔曲线的基本使用

早在很久很久以前,QQ就实现了"一键下班"功能.何为"一键下班"?当你QQ有信息时,下部会有信息数量提示红点,点击拖动之后,就会出现"一键下班"效果.本文将结合github上关于此功能的一个简单实现,介绍这个功能的基本实现思路. 项目地址 https://github.com/chenupt/BezierDemo 最终实现效果 实现原理解析 我个人感觉,这个效果实现的很漂亮啊!那么咱们就来看看实现原理是什么~ 注:下面内容请参照项目源码观看. 其

svg path中的贝塞尔曲线

首先介绍以下什么是贝塞尔曲线 贝塞尔曲线又叫贝茨曲线(Bezier),由两个端点以及若干个控制点组成,只有两个端点在曲线上,控制点不在曲线上,只是控制曲线的走向. 控制点个数为0时,它是一条直线; 控制点个数为1时,它是二次贝塞尔曲线; 控制点个数为2时,它是三次贝塞尔曲线: .... 数学公式 二次贝塞尔曲线 p0,p2是起始点,p1是控制点 分别把p0,p1,p2点的x,y坐标带入,求出曲线上的点的x,y坐标 三次贝塞尔曲线 p0,p3是起始点,p1,p2是控制点 svg的path中与贝塞尔

贝塞尔曲线 控制点

摘自:http://blog.chinaunix.net/uid-20622737-id-3161025.html //贝塞尔曲线,输入参数分别为起点坐标,第一控制点坐标,终点坐标 //curve4还增加了第二控制点坐标,作为参数 agg::curve3 curve(20, 20, 130, 130, 600, 240); agg::conv_stroke<agg::curve3> stroke2(curve); ras.add_path(stroke2); agg::render_scanl

【转~】初识贝塞尔曲线(B&#233;zier curve)

本文图文大多转自http://www.html-js.com/article/1628 QAQ我居然去扒维基,,,看不懂啊,,,我要去补数学,,, 在做变形小鸡的时候用到CSS3 transition-timing-function 属性,其语法如下: transition-timing-function: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n); 总而言之可以用cubic-bezier(n,n,n,n)的形式

从Android动画到贝塞尔曲线

基础知识: 动画通过连续播放一系列画面,给视觉造成连续变化的图画.很通俗的一种解释.也很好理解.那么我们先来一个案例看看. 动画案例:百度贴吧小熊奔跑 效果: topic.gif 代码: <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:

贝塞尔曲线扫盲

相信很多同学都知道"贝塞尔曲线"这个词,我们在很多地方都能经常看到.但是,可能并不是每位同学都清楚地知道,到底什么是"贝塞尔曲线",又是什么特点让它有这么高的知名度. 贝塞尔曲线的数学基础是早在 1912 年就广为人知的伯恩斯坦多项式.但直到 1959 年,当时就职于雪铁龙的法国数学家 Paul de Casteljau 才开始对它进行图形化应用的尝试,并提出了一种数值稳定的 de Casteljau 算法.然而贝塞尔曲线的得名,却是由于 1962 年另一位就职于雷

贝塞尔曲线的使用

什么是贝塞尔曲线 它主要用在Andorid中某些自定义VIew的时候需要绘制某些曲线.它只要有些名词介绍: 数据点:通常指一条路径的起始点和终止点 控制点:控制点决定可一条路径的弯曲轨迹,根据控制的点的个数,贝塞尔曲线被分为一阶贝塞尔曲线(0个控制点).二阶贝塞尔曲线(1个控制点).三阶贝塞尔曲线(2个控制点) 在平时开发中主要掌握二阶和三阶贝塞尔曲线 二阶贝塞尔曲线 由上图看,P0是起点,P2是终点.P1是控制点,t是一个系数,表示从0-1的变化过程,红色的线就是最终画出的曲线.其中主要是用到