標籤:interpolating bezier curve animation system math
i_dovelemon
來源:CSDN
日期:2015 / 7 / 11
主題:Interpolate,Bezier Curve
引言在遊戲開發中,諸如動畫系統,路徑計算等等操作,都會遇到對數值進行插值的問題。從今天開始,將會陸陸續續的向大家介紹什麼是插值技術?以及在電腦視頻遊戲開發中經常使用的插值技術有哪些。插值技術(Interpolate Technology),是通過數學計算的方式,將兩個值之間的部分進行平滑過渡的一種技術方案。這樣的技術可以在諸如動畫系統等遊戲內容中得到使用。就拿動畫系統舉例,現在的動畫系統大都流行一種基於主要畫面格的動畫。美術人員在一些動畫製作軟體中,如flash,製作好動畫的主要畫面格,然後就將該動畫匯出成一個檔案。這個檔案中只儲存了每一個動畫的關鍵運動部分。那麼,當我們在遊戲中使用的時候,就需要通過程式來補充每兩個主要畫面格之間的幀狀態資料。這種通過兩個首尾值來構建中間部分值的技術就稱之為插值技術。本文就會向大家展示其中一種經常使用的插值技術的數學技術。它的實際應用將在後續章節向大家展示。
Bezier CurveBezier Curve,即為貝茲路徑。它是一些曲線幾何的總稱。在本文中,將會向大家展示三種Bezier Curve,分別是Linear Bezier Curve, Quadratic Bezier Curve, Cubic Bezier Curv。這三種Bezier Curve都是經常用到的曲線,並且分別是一次曲線,二次曲線和三次曲線。其他更高維度曲線將不再講述。關於Bezier Curve的詳細講解,大家可以看下這篇Wiki:Bezier Curve.
Linear Bezier Curve一次Bezier Curve,被稱為Linear Bezier Curve,它實際上指的就是一條直線,並沒有任何的彎曲度。所以,使用一次Bezier Curve進行插值的技術,又被稱為值Linear Interpolating(線性插值)。線性插值技術的應用十分廣泛,除了在動畫系統中使用到之外,在3D圖形的光柵化階段也用來對頂點資料和紋理資料進行插值計算。下面給出線性插值的公式:B(t) = p0 + (p1 - p0) * t [0<=t <= 1] (1)上面公式中的t,表示了p0和p1之間某個時刻,而B(t)為此時曲線的狀態。因為是直線,所以這個很容易理解。
Quadratic Bezier Curve二次曲線的公式是在一次曲線的基礎上推導來的,數學推導部分同樣可以到上面的wiki中找到,這裡將直接給出公式:B(t) = (1 - t) ^2 * p0 + 2 * (1 - t) * t * p1 + t^2 * p2 (2)
Cubic Bezier Curve三次曲線的公式如下所示:B(t) = (1 - t)^3 * p0 + 3 * (1 - t) ^2 * t * p1 + 3 * (1 - t ) * t^2 * p2 + t^3 * p3 (3)
繪製Bezier Curve下面的代碼示範了如何繪製Linear Bezier,Quadratic Bezier以及Cubic Bezier。代碼使用的是javascript來編寫:
<span style="font-family:Microsoft YaHei;"><html><script>var _2dContext = 0;/*Begin Solve Bezier Curve method*/function LinearBezierCurve(p0,p1,t){return p0 + (p1 - p0) * t;}function QuadBezierCurve(p0,p1,p2,t){var current = 0;var InvT = 1 - t;var InvT_2 = InvT * InvT;var T2 = t * t;current = InvT_2 * p0;current += 2 * InvT * t * p1;current += T2* p2;return current;}function CubicBezierCurve(p0,p1,p2,p3,t){var current = 0;var InvT = 1 - t;var InvT_2 = InvT * InvT;var InvT_3 = InvT_2 * InvT;var T2 = t * t;var T3 = T2 * t;current += InvT_3 * p0;current += 3 * InvT_2 *t * p1;current += 3 * InvT * T2 * p2;current += T3 * p3;return current;}/*End Solve Bezier Curve*///Draw a point in the cavansfunction DrawPoint(context,x,y,color){context.beginPath();context.moveTo(x,y);context.lineTo(x + 1,y);context.closePath();context.strokeStyle = color;context.stroke();}/*Begin Draw Bezier Curve*/function DrawLinearBezierCurve(context,p0_x,p0_y,p1_x,p1_y,step,color){var t = 0;for(;t<=1;t+=step){//Calculate the new positionvar current_x = LinearBezierCurve(p0_x,p1_x,t);var current_y = LinearBezierCurve(p0_y,p1_y,t);//Draw the pointDrawPoint(context,current_x,current_y,color);}}function DrawQuadBezierCurve(context, p0_x,p0_y,p1_x,p1_y,p2_x,p2_y,step,color){var t = 0;for(;t<=1;t+=step){//Calculate the new positionvar current_x = QuadBezierCurve(p0_x,p1_x,p2_x,t);var current_y = QuadBezierCurve(p0_y,p1_y,p2_y,t);//Draw the pointDrawPoint(context,current_x,current_y,color);}}function DrawCubicBezierCurve(context,p0_x,p0_y,p1_x,p1_y,p2_x,p2_y,p3_x,p3_y,step,color){var t = 0;for(;t<=1;t+=step){//Calculate the new positionvar current_x = CubicBezierCurve(p0_x,p1_x,p2_x,p3_x,t);var current_y = CubicBezierCurve(p0_y,p1_y,p2_y,p3_y,t);//Draw the pointDrawPoint(context,current_x,current_y,color);}}/*End Draw Bezier Curve*/function gameInit(){//Get the canvas context_2dContext = document.getElementById("canvas").getContext("2d");//enable game loopsetInterval(gameLoop,100.0);}function gameLoop(){//Clear the canvas_2dContext.clearRect(0,0,1024,768);//Draw the linear bezier curveDrawLinearBezierCurve(_2dContext,100,100,1000,100,0.001,"rgb(255,0,0)");//Draw the Quadratic bezier curvevar qp1_x = Math.random() * 1024;var qp1_y = Math.random() * 768;DrawQuadBezierCurve(_2dContext,100,400,qp1_x,qp1_y,1000,400,0.001,"rgb(0,255,0)");//Draw the Cubic bezier curvevar cp1_x = Math.random() * 1024;var cp1_y = Math.random() * 768;var cp2_x = Math.random() * 1024;var cp2_y = Math.random() * 768;DrawCubicBezierCurve(_2dContext,100,600,cp1_x,cp1_y,cp2_x,cp2_y,1000,600,0.001,"rgb(0,0,255)");}</script><body><body onLoad="gameInit();"><canvas id="canvas" width="1024" height="768">您的瀏覽器不支援Canvas特性!!!請使用Chrome,Firefox!!</canvas></body></html></span>
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
插值技術之Bezier插值(1) -- Bezier Curve