【转】贝塞尔曲线介绍
原文鏈接:
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
- path移動到起點
- 確定直線的終點
- 調用canvas繪制貝塞爾曲線
??好了,到這里一階的一條直線就完成了;?
??但是這個完全沒任何卵用啊,就一條直線有木有!!
??但是,我們可以一直畫下去,就像這樣:
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
?
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
這一篇文章會完整的介紹如何通過貝塞爾曲線實現愛心點贊的效果,如果實在看不懂,可以看第一篇貝塞爾曲線的簡介,還有第二篇安卓中的簡單使用;
好了,終于到了放大招的時候了,真實憋了很久了?
?
先做一些準備工作,繪制各種顏色的紅心:
這里面比較關鍵的代碼只有是 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;}@Overridepublic 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;}}?
這個很簡單,就是單純的使用公式了,所以說想要繪制復雜的軌跡,我還是要重新拾起來被扔進糞坑的小學數學課本重新看看,當真是熏得淚流滿面啊!!?
接下來就很簡單了,只要不停使用屬性動畫,不斷變換位置就好了;
就是這么簡單,完全沒有難度啊有木有!!!?
總的來說還是三步:?
第一
好了,到這里我這一系列的文章就結束了,兩天水時間搞的,感覺稍微有點水,但是就這樣啦,畢竟本身不是很難的東西,有什么問題可以問我,有時間一定會耐心解答的;
最后附上源碼:https://github.com/sangxiaonian/BezierIntroduce.git
?
轉載于:https://www.cnblogs.com/ryq2014/p/8432318.html
總結
以上是生活随笔為你收集整理的【转】贝塞尔曲线介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分享一个关于网站适应性的解决方案
- 下一篇: 一次通过软考中项