中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

巧用二階貝賽爾曲線繪制粒子路徑

發布時間:2020-06-30 00:16:43 來源:網絡 閱讀:582 作者:googlingman 欄目:開發技術

引文

URL:http://zhuxianzhong.blog.51cto.com/user_index.php?action=addblog_new


一階貝賽爾曲線上的由兩個點確定  P0 和P1,當t在0--->1區間上遞增時,根據式(1)

   會得到多個點的坐標,其實這些的點就是一條直線上的點。

               B(t) = (1-t)P0 + tP1--------------------------------------(1)

          即:

               B(t).x = (1-t)P0.x + tP1.x

               B(t).y = (1-t)P0.y + tP1.y

     

       二階貝賽爾曲線由3個點確定,它可以理解成是這樣的一階貝賽爾曲線:確定該一階貝賽爾曲線的兩個點是變化的。

      這兩個點(設分別為Pm,Pn)是怎樣變化的呢,這兩個點又分別是(P0,P1)確定的一階貝賽爾曲線和(P1,P2)確定的一階貝賽爾

      曲線上的點。

            于是有了2階貝賽爾曲線的公式

            Pm(t) = (1-t)P0 + tP1

            Pn(t)  = (1-t)P1 + tP2

            B(t)  = (1-t)Pm(t) + tPn(t) = (1-t)^2 P0 + 2(1-t)tP1+ t^2P2

        以此類推可以得到3階貝賽爾曲線,是不是很簡單?



引文2

URL:http://www.cnblogs.com/jay-dong/archive/2012/09/26/2704188.html

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處的切線。

 

三階貝塞爾曲線:

巧用二階貝賽爾曲線繪制粒子路徑

巧用二階貝賽爾曲線繪制粒子路徑

 

 

通用公式:

 

巧用二階貝賽爾曲線繪制粒子路徑

高階貝塞爾曲線:

4階曲線:

巧用二階貝賽爾曲線繪制粒子路徑

5階曲線:

巧用二階貝賽爾曲線繪制粒子路徑

 

http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html

 

Following the construction of a Bézier curve, the next important task is to find the point C(u) on the curve for a particular u. A simple way is to plug u into every basis function, compute the product of each basis function and its corresponding control point, and finally add them together. While this works fine, it is not numerically stable (i.e., could introduce numerical errors during the course of evaluating the Bernstein polynomials).

In what follows, we shall only write down the control point numbers. That is, the control points are 00 for P001 for P1, ..., 0i for Pi, ..., 0n for Pn. The 0s in these numbers indicate the initial or the 0-th iteration. Later on, it will be replaced with 123 and so on.

The fundamental concept of de Casteljau's algorithm is to choose a point C in line segment AB such that C divides the line segment AB in a ratio of u:1-u (i.e., the ratio of the distance between A and C and the distance between A and B is u). Let us find a way to determine the point C.

 

巧用二階貝賽爾曲線繪制粒子路徑

The vector from A to B is B - A. Since u is a ratio in the range of 0 and 1, point C is located at u(B - A). Taking the position of A into consideration, point C is A + u(B - A) = (1 - u)A + uB. Therefore, given a u, (1 - u)A + uB is the point C between A and B that divides AB in a ratio of u:1-u.

The idea of de Casteljau's algorithm goes as follows. Suppose we want to find C(u), where u is in [0,1]. Starting with the first polyline, 00-01-02-03...-0n, use the above formula to find a point 1i on the leg (i.e. line segment) from 0i to0(i+1) that divides the line segment 0i and 0(i+1) in a ratio of u:1-u. In this way, we will obtain n points 101112, ...., 1(n-1). They define a new polyline of n - 1 legs.

 

巧用二階貝賽爾曲線繪制粒子路徑

In the figure above, u is 0.4. 10 is in the leg of 00 and 0111 is in the leg of 01 and 02, ..., and 14 is in the leg of04 and 05. All of these new points are in blue.

The new points are numbered as 1i's. Apply the procedure to this new polyline and we shall get a second polyline of n - 1 points 2021, ..., 2(n-2) and n - 2 legs. Starting with this polyline, we can construct a third one of n - 2 points 30,31, ..., 3(n-3) and n - 3 legs. Repeating this process n times yields a single point n0. De Casteljau proved that this is the point C(u) on the curve that corresponds to u.

Let us continue with the above figure. Let 20 be the point in the leg of 10 and 11 that divides the line segment 10 and 11in a ratio of u:1-u. Similarly, choose 21 on the leg of 11 and 1222 on the leg of 12 and 13, and 23 on the leg of 13and 14. This gives a third polyline defined by 202122 and 23. This third polyline has 4 points and 3 legs. Keep doing this and we shall obtain a new polyline of three points 3031 and 32. From this fourth polyline, we have the fifth one of two points 40 and 41. Do it once more, and we have 50, the point C(0.4) on the curve.

This is the geometric interpretation of de Casteljau's algorithm, one of the most elegant result in curve design.

 

巧用二階貝賽爾曲線繪制粒子路徑

Actual Computation

Given the above geometric interpretation of de Casteljau's algorithm, we shall present a computation method, which is shown in the following figure.

 

巧用二階貝賽爾曲線繪制粒子路徑

First, all given control points are arranged into a column, which is the left-most one in the figure. For each pair of adjacent control points, draw a south-east bound arrow and a north-east bound arrow, and write down a new point at the intersection of the two adjacent arrows. For example, if the two adjacent points are ij and i(j+1), the new point is(i+1)j. The south-east (resp., north-east) bound arrow means multiplying 1 - u (resp.u) to the point at its tail, ij(resp.i(j+1)), and the new point is the sum.

Thus, from the initial column, column 0, we compute column 1; from column 1 we obtain column 2 and so on. Eventually, aftern applications we shall arrive at a single point n0 and this is the point on the curve. The following algorithm summarizes what we have discussed. It takes an array P of n+1 points and a u in the range of 0 and 1, and returns a point on the Bézier curve C(u).

 

  •  

    •  QiPi
      Input: array P[0:n] of n+1 points and real number u in [0,1] 
      Output: point on curve, C(u
      Working: point array Q[0:n

      for i := 0 to n do 
      for
       k := 1 to n do 
      return Q
      [0];

    • [

    • ] := (1 - 

    • )

    • [

    • ] + 

    •  

    •  + 1];

    • [

    • ]; // save input 

    •  QiuQiuQifor i := 0 to n - k do 

    • [

    • ] := 

    • [

 

巧用二階貝賽爾曲線繪制粒子路徑

A Recurrence Relation

The above computation can be expressed recursively. Initially, let P0,j be Pj for j = 0, 1, ..., n. That is, P0,j is the j-th entry on column 0. The computation of entry j on column i is the following:

 

巧用二階貝賽爾曲線繪制粒子路徑

More precisely, entry Pi,j is the sum of (1-u)Pi-1,j (upper-left corner) and uPi-1,j+1 (lower-left corner). The final result (i.e., the point on the curve) is Pn,0. Based on this idea, one may immediately come up with the following recursive procedure:

 

  •  

    •  function deCasteljau(i,j
      begin 
      end

    •  

    •  (1-

    • )*

    • (

    • -1,

    • ) + 

    • *

    • (

    •  return P0,j
      returnu deCasteljauiju deCasteljauijif i = 0 then 
      else
       

    • +1)

    • -1,

This procedure looks simple and short; however, it is extremely inefficient. Here is why. We start with a call todeCasteljau(n,0) for computing Pn,0. The else part splits this call into two more calls, deCasteljau(n-1,0) for computing Pn-1,0 and deCasteljau(n-1,1) for computing Pn-1,1.

 

巧用二階貝賽爾曲線繪制粒子路徑

Consider the call to deCasteljau(n-1,0). It splits into two more calls, deCasteljau(n-2,0) for computing Pn-2,0 anddeCasteljau(n-2,1) for computing Pn-2,1. The call to deCasteljau(n-1,1) splits into two calls, deCasteljau(n-2,1) for computing Pn-2,1 and deCasteljau(n-2,2) for computing Pn-2,2. Thus, deCasteljau(n-2,1) is called twice. If we keep expanding these function calls, we should discover that almost all function calls for computing Pi,j are repeated, not once but many times. How bad is this? In fact, the above computation scheme is identical to the following way of computing then-th Fibonacci number:

  •  

    •  function Fibonacci(n)
      beginend

    •  1 

    •  

    •  (

    • -1) + 

    •  return
      returnFibonaccinFibonaccinif n = 0 or n = 1 then 
      else

    • -2)

    •  (

This program takes an exponential number of function calls (an exercise) to compute Fibonacci(n). Therefore, the above recursive version of de Casteljau's algorithm is not suitable for direct implementation, although it looks simple and elegant!

 

巧用二階貝賽爾曲線繪制粒子路徑

An Interesting Observation

The triangular computation scheme of de Casteljau's algorithm offers an interesting observation. Take a look at the following computation on a Bézier curve of degree 7 defined by 8 control points 0001, ..., 07. Let us consider a set of consecutive points on the same column as the control points of a Bézier curve. Then, given a u in [0,1], how do we compute the corresponding point on this Bézier curve? If de Casteljau's algorithm is applied to these control points, the point on the curve is the opposite vertex of the equilateral's base formed by the selected points!

 

巧用二階貝賽爾曲線繪制粒子路徑

For example, if the selected points are 020304 and 05, the point on the curve defined by these four control points that corresponds to u is 32. See the blue triangle. If the selected points are 1112 and 13, the point on the curve is31. See the yellow triangle. If the selected points are 30313233 and 34, the point on the curve is 70.

By the same reason, 70 is the point on the Bézier curve defined by control points 60 and 61. It is also the point on the curve defined by 5051 and 52, and on the curve defined by 404142 and 43. In general, if we select a point and draw an equilateral as shown above, the base of this equilateral consists of the control points from which the selected point is computed.


可能性應用分析

  好了,有了前面的足夠多的理論指導,我們在cococs2d-x開發中如何使用呢?思路有多種,方法也有多種。我當前的應用需求是,要繪制一條從A點到B點的一條粒子流路徑。其中這兩個點是UI編輯器確定的屏幕上的固定點,而且繪制路徑不要是直線式,否則太板了--難看!當然,要求也不是非常高,過此兩點大致畫一曲線即可。于是,我可以在此兩點確定的直接的某一側適當估計一個點,然后通過這三個點畫一個二階Bezier曲線,這個應該是好辦的。這樣大致的曲線正是我實現粒子系統的流動路徑所需要的!


  先分析一下我使用上述大致指導思路實現的一只蝴蝶沿著一個封閉曲線飛動的動畫相應代碼:

   

ccBezierConfig bezier1,bezier2;
    bezier1.controlPoint_1 = ccp(0, 0);
    bezier1.controlPoint_2 = ccp(-VisibleRect::right().x*2/3, VisibleRect::top().y*2/3);
    bezier1.endPosition = ccp(-VisibleRect::right().x*2/3-130,236);
    CCActionInterval*  bezierForward1 = CCBezierBy::create(10, bezier1);
    //below routine
    bezier2.controlPoint_1 = ccp(0, 0);
    bezier2.controlPoint_2 = ccp(-130, -236);
    bezier2.endPosition = ccp(VisibleRect::right().x*2/3+130,-236);
    CCActionInterval*  bezierForward2 = CCBezierBy::create(10, bezier2);
    CCActionInterval*  seq = CCSequence::create(
        bezierForward1,
        bezierForward2,
        NULL);
    CCRepeatForever*  repeat_01 = CCRepeatForever::create(seq);
    arm_butterfly_01->runAction(repeat_01);

  上述代碼思路是:把兩個BEZIER曲線連接起來,形成一個封閉曲線,從而形成動畫路徑。使用這種思路,你可以實現幾乎任意曲線方案。對于粒子流動路徑的應用自然也十分類似。


補充:

  當起點與終點是一條水平線或者豎線時,確定線外的那個控制點相當EASY。若是AB點的連接線是一個傾斜直線時大致不估略微麻煩些。我有時使用UI編輯器中旋轉的一個1X1像素點作為PLACEHOLDER,然后為后臺代碼所取出使用。當然,直接在后臺代碼中分析確定這樣的點也OK。



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

剑阁县| 黄冈市| 明水县| 壤塘县| 苍南县| 寿光市| 久治县| 潞西市| 麻阳| 尚义县| 西青区| 昆山市| 邵武市| 高陵县| 恩施市| 台湾省| 揭西县| 襄汾县| 柳江县| 滦平县| 莒南县| 贵南县| 江都市| 清水县| 高邑县| 盐城市| 红安县| 临沧市| 寻甸| 武清区| 溧水县| 婺源县| 宣恩县| 珠海市| 南宁市| 新邵县| 临朐县| 巨野县| 霍邱县| 巴彦县| 连山|