• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            eryar

            PipeCAD - Plant Piping Design Software.
            RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
            posts - 603, comments - 590, trackbacks - 0, articles - 0

            B-Spline Curve Library in Open Cascade

            Posted on 2013-03-12 20:48 eryar 閱讀(9636) 評(píng)論(1)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

            B-Spline Curve Library in Open Cascade

            Open Cascade中的B樣條曲線庫(kù)

            eryar@163.com

            摘要Abstract:簡(jiǎn)要介紹Open Cascade中的B樣條曲線庫(kù)BSplCLib的使用方法,并且結(jié)合源程序來對(duì)Open Cascade中的B樣條曲線的組成部分如節(jié)點(diǎn)矢量、重復(fù)度等概念進(jìn)行介紹,以及通過對(duì)計(jì)算B樣條基函數(shù)的算法進(jìn)行分析,加深對(duì)B樣條曲線概念的理解。

            關(guān)鍵字Key Word:B Spline Curve、Open Cascade、Knot Vector、Multiplicity

             

            一、 概述 Overview

            1946年由Schoenberg提出了B樣條理論,給出了B樣條的差分表達(dá)式;1972年de Boor和Cox分別獨(dú)立給出了關(guān)于B樣條的標(biāo)準(zhǔn)算法。Gordon和Riesenfeld又把B樣條理論用于形狀描述,最終提出了B樣條方法。用B樣條基替代了Bernstein基,構(gòu)造出B樣條曲線,這種方法繼承了Bezier方法的一切優(yōu)點(diǎn),克服了Bezier方法存在的缺點(diǎn),較成功地解決了局部控制問題,又輕而易舉地在參數(shù)連續(xù)性基礎(chǔ)上解決了連接問題,從而使自由曲線曲面形狀的描述問題得到較好解決。

            p次B樣條曲線的定義為:

            wps_clip_image-15140

            其中:

            l Pi是控制頂點(diǎn)(control point);

            l Ni,p(u)是定義在非周期節(jié)點(diǎn)矢量上的p次B樣條基函數(shù);

            有很多方法可以用來定義B樣條基函數(shù)以及證明它的一些重要性質(zhì)。例如,可以采用截尾冪函數(shù)的差商定義,開花定義,以及由de Boor和Cox等人提出的遞推公式等來定義。我們這里采用的是遞推定義方法,因?yàn)檫@種方法在計(jì)算機(jī)實(shí)現(xiàn)中是最有效的。

            令U={u0,u1,…,um}是一個(gè)單調(diào)不減的實(shí)數(shù)序列,即ui<=ui+1,i=0,1,…,m-1。其中,ui稱為節(jié)點(diǎn),U稱為節(jié)點(diǎn)矢量,用Ni,p(u)表示第i個(gè)p次B樣條基函數(shù),其定義為:

            wps_clip_image-10013

            B樣條基有如下性質(zhì):

            a) 遞推性;

            b) 局部支承性;

            c) 規(guī)范性;

            d) 可微性;

            根據(jù)B樣條曲線定義可知,給定控制頂點(diǎn)Pi(control points),曲線次數(shù)p(degree)及節(jié)點(diǎn)矢量U(knot vectors),B樣曲線也就確定。對(duì)于有理B樣條曲線,還需要參數(shù)權(quán)重(weights)。

            二、 OCC中的B樣條曲線庫(kù) BSplCLib in OCC

            在Open Cascade中的工具箱(Toolkit)TKMath中的包(package)BSplCLib是B樣條曲線庫(kù),為B樣條曲線曲面的計(jì)算提供了支持。它提供了三方面的功能:

            l 對(duì)節(jié)點(diǎn)矢量(knot vectors)及重復(fù)度(multiplicities)的管理;

            l 對(duì)多維樣條的支持,即B樣條方法中控制頂點(diǎn)的維數(shù)可以是任意維數(shù)(dimension);

            l 二維和三維樣條曲線的方法;

            Open Cascade中的B樣條曲線由下列數(shù)據(jù)項(xiàng)定義:

            定義

            變量類型

            變量名稱

            控制頂點(diǎn)control points

            TColgp_Array1OfPnt

            Poles

            權(quán)重weights

            TColStd_Array1OfReal

            Weights

            節(jié)點(diǎn)knots

            TColStd_Array1OfReal

            Knots

            重?cái)?shù)multiplicities

            TColStd_Array1OfInteger

            Mults

            次數(shù)degree

            Standard_Integer

            Degree

            周期性periodicity

            Standard_Boolean

            Periodic


            B樣條曲線庫(kù)BSplCLib提供了一些基本幾何算法:

            l B樣條基函數(shù)及其導(dǎo)數(shù)的計(jì)算BSplCLib::EvalBsplineBasis();

            l 節(jié)點(diǎn)插入BSplCLib::InsertKnot();

            l 節(jié)點(diǎn)去除BSplCLib::RemoveKnot();

            l 升階BSplCLib::IncreaseDegree();

            l 降階;

            結(jié)合《The NURBS Book》和Open Cascade中的BSplCLib的源程序,可以高效的學(xué)習(xí)NURBS。《The NURBS Book》中有詳細(xì)的理論推導(dǎo)及算法描述,而Open Cascade中有可以用來實(shí)際使用的程序。理論聯(lián)系實(shí)際,有助于快速理解NURBS的有關(guān)概念及其應(yīng)用。

            三、 OCC中B樣條曲線庫(kù)的節(jié)點(diǎn)和重?cái)?shù)Knots and Multiplicity in BSplCLib

            由B樣條曲線的可微性可知,節(jié)點(diǎn)的重?cái)?shù)與B樣條曲線的連續(xù)性相關(guān)。在節(jié)點(diǎn)區(qū)間內(nèi)部,Ni,p(u)是無限次可微的,因在每個(gè)節(jié)點(diǎn)區(qū)間內(nèi)部,它是一個(gè)多項(xiàng)式。在節(jié)點(diǎn)處Ni,p(u)是p-k次連續(xù)的,其中k是節(jié)點(diǎn)的重復(fù)度(multiplicity,有時(shí)也稱為重?cái)?shù))。因此,增加次數(shù)p將提高曲線的連續(xù)性,而增加節(jié)點(diǎn)的重復(fù)度則使連續(xù)性降低。

            重復(fù)度(multiplicity,有時(shí)也稱為重?cái)?shù))有兩種不同的理解方式:

            l 節(jié)點(diǎn)在節(jié)點(diǎn)矢量中的重復(fù)度;

            l 節(jié)點(diǎn)相對(duì)于一個(gè)特定的基函數(shù)的重復(fù)度;

            在Open Cascade中對(duì)重復(fù)度的理解是前者,即節(jié)點(diǎn)在節(jié)點(diǎn)矢量中的重復(fù)度。下面結(jié)合源程序來進(jìn)行說明。

            函數(shù)BSplCLib::Knots()用來將給定的節(jié)點(diǎn)矢量(節(jié)點(diǎn)序列knot sequence)轉(zhuǎn)換為節(jié)點(diǎn)的重復(fù)度不大于1的Knots數(shù)組和每個(gè)節(jié)點(diǎn)對(duì)應(yīng)的重復(fù)度Mults數(shù)組,且數(shù)據(jù)Knots和Mults的長(zhǎng)度必由函數(shù)BSplCLib::KnotsLength()得到。Knots()函數(shù)的源程序如下所示:

             

            //======================================================================= 

            //function : Knots 

            //purpose  : Computes  the  sequence   of knots Knots  without repetition   

            //           of the  knots  of multiplicity  greater than 1. 

            //           Length  of <Knots> and  <Mults> must be KnotsLength(KnotSequence,Periodic). 

            //======================================================================= 

            void BSplCLib::Knots(const TColStd_Array1OfReal& SeqKnots,  

                      TColStd_Array1OfReal 
            &knots, 

                      TColStd_Array1OfInteger 
            &mult, 

            //         const Standard_Boolean Periodic) 

            const Standard_Boolean ) 



               Standard_Real val 
            = SeqKnots(1); 

               Standard_Integer kk
            =1

               knots(kk) 
            = val; 

               mult(kk)  
            = 1

            for (Standard_Integer jj=2;jj<=SeqKnots.Length();jj++

                 


            // test on strict equality on nodes 

            if (SeqKnots(jj)!=val) 

                     


                       val 
            = SeqKnots(jj); 

                       kk
            ++

                       knots(kk) 
            = val; 

                       mult(kk)  
            = 1

                     }
             

            else 

                     


                       mult(kk)
            ++

                     }
             

                 }
             

            }
             


            從上述代碼可知,直接使用了不等于來判斷兩個(gè)節(jié)點(diǎn)的值是否相同,而沒有采用誤差處理,即嚴(yán)格的相等比較。程序?qū)⒐?jié)點(diǎn)重復(fù)度不大于1的節(jié)點(diǎn)及其相應(yīng)的重復(fù)度分別保存到knots和mult中。

            四、 B樣條曲線的分類 B Spline Curve Type

            B樣條曲線一般按定義基函數(shù)的節(jié)點(diǎn)序列是否等距(均勻)分為均勻B樣條曲線(Uniform B-Spline Curve)和非均勻B樣條曲線(Non Uniform B-Spline Curve)。

            B樣條曲線按節(jié)點(diǎn)序列中節(jié)點(diǎn)分布情況不同,又分為四種類型:均勻B樣條曲線、準(zhǔn)均勻B樣條曲線、分段Bezier曲線、一般非均勻B樣條曲線。設(shè)給定特征多邊形頂點(diǎn)Vi,i=0,1,…,n,曲線次數(shù)k,則有:

            l 均勻B樣條曲線(uniform B-Spline curve):節(jié)點(diǎn)序列中節(jié)點(diǎn)沿參數(shù)軸均勻或等距分布,即所有節(jié)點(diǎn)區(qū)間長(zhǎng)度為大于零的常數(shù)(constant):

            wps_clip_image-14311

            l 準(zhǔn)均勻B樣曲線(quasi-uniform B-Spline curve):其節(jié)點(diǎn)序列中兩端節(jié)點(diǎn)具有重復(fù)度k+1,而所有內(nèi)節(jié)點(diǎn)均勻分布,具有重復(fù)度1。

            l 分段Bezier曲線(piecewise Bezier curve):其節(jié)點(diǎn)序列中兩端節(jié)點(diǎn)重復(fù)度與準(zhǔn)均勻B樣條曲線的相同,所不同的是所有內(nèi)節(jié)點(diǎn)重復(fù)度為k。

            l 非均勻B樣條曲線(general non-uniform B-Spline curve):這是對(duì)任意分布的節(jié)點(diǎn)序列,只要在數(shù)學(xué)上成立,即節(jié)點(diǎn)序列非遞減,都可取。

            在基礎(chǔ)類模塊(Module FoundationClasses)的工具箱(Toolkit TKMath)中的包(GeomAbs)中有對(duì)B樣樣條曲線類型的定義,源程序如下所示:

             

            //!  This enumeration is used to note specific curve form. <br> 

            enum GeomAbs_BSplKnotDistribution { 

            GeomAbs_NonUniform, 

            GeomAbs_Uniform, 

            GeomAbs_QuasiUniform, 

            GeomAbs_PiecewiseBezier 

            }; 

             

            而類BSplCLib主要是用來管理節(jié)點(diǎn)和重復(fù)度的,所有將節(jié)點(diǎn)和重復(fù)度也進(jìn)行了分類。根據(jù)節(jié)點(diǎn)矢量是否均勻分布,將節(jié)點(diǎn)分配方式(Knot Distribution)分為:均勻(BSplCLib_Uniform)和非均勻(BSplCLib_NonUniform)。源程序如下所示:

             

            enum BSplCLib_KnotDistribution { 

            BSplCLib_NonUniform, 

            BSplCLib_Uniform 

            }; 

             

            根據(jù)重復(fù)度數(shù)組將重復(fù)度的分配方式分為如下三種類型:

            n BSplCLib_Constant:重復(fù)度都相同;

            n BSplCLib_QuasiConstant:首、尾節(jié)點(diǎn)的重復(fù)度與內(nèi)部節(jié)點(diǎn)的重復(fù)度不同;

            n BSplClib_NonConstant:其它情況;

            源程序如下所示:

             

            enum BSplCLib_MultDistribution { 

            BSplCLib_NonConstant, 

            BSplCLib_Constant, 

            BSplCLib_QuasiConstant 

            }; 

             

            判斷節(jié)點(diǎn)矢量和重復(fù)度矢量類型分別由下列函數(shù)實(shí)現(xiàn):

            l BSplCLib::KnotForm();

            l BSplCLib::MultForm();

            具體的判斷方法可以查看源程序。

            將節(jié)點(diǎn)分布方式與重復(fù)度的分布方式進(jìn)行組合,可以得出B樣條曲線的那幾種類型。

            五、 B樣條基函數(shù)的計(jì)算 Evaluate the B-Spline Basis

            B樣條基函數(shù)的計(jì)算主要使用了B樣條基了函數(shù)的遞推公式(Cox-deBoor公式)的局部支撐性質(zhì),如下所示:

            wps_clip_image-21079

            直接由定義可知:

            l Ni,0(u)是一個(gè)階梯函數(shù),它在半開區(qū)間u∈[ui, ui+1)外都為零;

            l 當(dāng)次數(shù)p>0時(shí),Ni,p(u)是兩個(gè)p-1次基函數(shù)的線性組合;

            l 計(jì)算一組基函數(shù)需要事先指定節(jié)點(diǎn)矢量U和次數(shù)p;

            l 半開區(qū)間[ui,ui+1)稱為第i個(gè)節(jié)點(diǎn)區(qū)間(knot span),它的長(zhǎng)度可以為零,因?yàn)橄噜徆?jié)點(diǎn)可以是相同的;

            l 計(jì)算p次基函數(shù)的過程可以生成一個(gè)如下形式的三角形陳列:

            wps_clip_image-31692

            B樣條有局部支撐性,即若u不在區(qū)間[ui, ui+p+1),則Ni,p(u)=0。可從下面的三角形中看出N1,3是N1,0、N2,0、N3,0和N4,0的線性組合,而N1,0在區(qū)間[u1, u2)上非零,N2,0在區(qū)間[u2,u3)上非零,N3,0在區(qū)間[u3,u4)上非零,N4,0在區(qū)間[u4,u5)上非零,所以N1,3僅在區(qū)間[u1,u5)上非零。

            在任意給定的節(jié)點(diǎn)區(qū)間[uj,uj+1)內(nèi),最多有p+1個(gè)是非零的,它們是Nj-p,p、Nj-p+1、…、Nj,p。例如,在[u3,u4)上,零次基函數(shù)中只有N3,0是非零的,一次基函數(shù)只有N2,1和N3,1是非零的,非零的三次基函數(shù)只有N0,3、N1,3、N2,3、N3,3。這個(gè)性質(zhì)如下圖所示:

            wps_clip_image-14220 wps_clip_image-13472

            上面兩幅圖中右邊的圖中所示的推算過程表明,給定節(jié)點(diǎn)序列U及B樣條曲線的次數(shù)p,給出任意一個(gè)u值,找出其所在的節(jié)點(diǎn)區(qū)間[ui,ui+1)上,最多有Ni-p,p,Ni-p+1,p,…,Ni,p個(gè)非零的基函數(shù)。

            例如我們根據(jù)遞推公式寫出二次基函數(shù)的一般形式,如下所示:

            wps_clip_image-25174

            當(dāng)給定的u值在區(qū)間[u3,u4)上即(i=3)時(shí),根據(jù)上面的三角形,得出下列重要結(jié)論:

            wps_clip_image-2192

            即這兩項(xiàng)不需要計(jì)算。另外一個(gè)重要結(jié)論就是圖中用相同顏色框中的部分是相同的,也就是下面程序中的變量temp表示的內(nèi)容。

            我們引入下面符號(hào):

            wps_clip_image-27970

            由二次基函數(shù)推出的三個(gè)公式可寫為:

            wps_clip_image-18620

            上述推導(dǎo)過程為《The NURBS Book》中的算法,算法代碼如下所示:

            wps_clip_image-10895

            理解了變量temp的意義之后,整個(gè)程序就很好理解了。

            將Open Cascade中計(jì)算基函數(shù)的算法是不同的,將其源程序摘抄如下所示:

             

            //======================================================================= 

            //function : Build BSpline Matrix 

            //purpose  : Builds the Bspline Matrix 

            //======================================================================= 

            Standard_Integer  

            BSplCLib::EvalBsplineBasis 

            //(const Standard_Integer              Side, // = 1 rigth side, -1 left side  

            (
            const Standard_Integer              , // = 1 rigth side, -1 left side  

            const  Standard_Integer              DerivativeRequest, 

            const  Standard_Integer              Order, 

            const  TColStd_Array1OfReal&         FlatKnots, 

            const  Standard_Real                 Parameter, 

            Standard_Integer
            &             FirstNonZeroBsplineIndex, 

            math_Matrix
            &                  BsplineBasis) 



            // the matrix must have at least DerivativeRequest + 1 

            //   row and Order columns 

            // the result are stored in the following way in 

            // the Bspline matrix  

            // Let i be the FirstNonZeroBsplineIndex and  

            // t be the parameter value, k the order of the  

            // knot vector, r the DerivativeRequest : 

            //    

            //   B (t)   B (t)                     B (t) 

            //    i       i+1                       i+k-1 

            //    

            //    (1)     (1)                       (1)  

            //   B (t)   B (t)                     B (t) 

            //    i       i+1                       i+k-1 

            //   

            // 

            // 

            // 

            //    (r)     (r)                       (r)  

            //   B (t)   B (t)                     B (t) 

            //    i       i+1                       i+k-1 

            // 

              Standard_Integer   

                ReturnCode, 

              ii, 

              pp, 

              qq, 

              ss, 

              NumPoles, 

              LocalRequest ; 

            //  ,Index ; 

              Standard_Real NewParameter, 

              Inverse, 

              Factor, 

              LocalInverse, 

              Saved ; 

            // , *FlatKnotsArray ; 

              ReturnCode 
            = 0 ; 

              FirstNonZeroBsplineIndex 
            = 0 ; 

              LocalRequest 
            = DerivativeRequest ; 

            if (DerivativeRequest >= Order) { 

                LocalRequest 
            = Order - 1 ; 



            if (BsplineBasis.LowerCol() != 1 || 

                  BsplineBasis.UpperCol() 
            < Order || 

                  BsplineBasis.LowerRow() 
            != 1 || 

                  BsplineBasis.UpperRow() 
            <= LocalRequest) { 

                ReturnCode 
            = 1

            goto FINISH ; 



              NumPoles 
            = FlatKnots.Upper() - FlatKnots.Lower() + 1 - Order ; 

              BSplCLib::LocateParameter(Order 
            - 1

                FlatKnots, 

                Parameter, 

                Standard_False, 

                Order, 

                NumPoles
            +1

                ii, 

                                        NewParameter) ; 

              FirstNonZeroBsplineIndex 
            = ii - Order + 1 ; 

              BsplineBasis(
            1,1= 1.0e0 ; 

              LocalRequest 
            = DerivativeRequest ; 

            if (DerivativeRequest >= Order) { 

                LocalRequest 
            = Order - 1 ; 



            for (qq = 2 ; qq <= Order - LocalRequest ; qq++) { 

                BsplineBasis(
            1,qq) = 0.0e0 ; 

            for (pp = 1 ; pp <= qq - 1 ; pp++) { 

            // 

            // this should be always invertible if ii is correctly computed  

            // 

                  Factor 
            = (Parameter - FlatKnots(ii - qq + pp + 1)) 

            / (FlatKnots(ii + pp) - FlatKnots(ii - qq + pp + 1)) ; 

                  Saved 
            = Factor *    BsplineBasis(1,pp) ; 

                  BsplineBasis(
            1,pp) *= (1.0e0 - Factor) ; 

                  BsplineBasis(
            1,pp) += BsplineBasis(1,qq) ; 

                  BsplineBasis(
            1,qq) = Saved ; 





            for (qq = Order - LocalRequest + 1 ; qq <= Order ; qq++) { 

            for (pp = 1 ; pp <= qq - 1 ; pp++) { 

                  BsplineBasis(Order 
            - qq + 2,pp) = BsplineBasis(1,pp) ; 



                BsplineBasis(
            1,qq) = 0.0e0 ; 

            for (ss = Order - LocalRequest + 1 ; ss <= qq ; ss++) { 

                  BsplineBasis(Order 
            - ss + 2,qq) = 0.0e0 ; 



            for (pp = 1 ; pp <= qq - 1 ; pp++) { 

                  Inverse 
            = 1.0e0 / (FlatKnots(ii + pp) - FlatKnots(ii - qq + pp + 1)) ; 

                  Factor  
            = (Parameter - FlatKnots(ii - qq + pp + 1)) * Inverse ; 

                  Saved 
            = Factor *                 BsplineBasis(1,pp) ; 

                  BsplineBasis(
            1,pp) *= (1.0e0 - Factor) ; 

                  BsplineBasis(
            1,pp) += BsplineBasis(1,qq) ; 

                  BsplineBasis(
            1,qq) = Saved ; 

                  LocalInverse 
            = (Standard_Real) (qq - 1* Inverse ; 

            for (ss = Order - LocalRequest + 1 ; ss <= qq ; ss++) { 

            Saved 
            = LocalInverse * BsplineBasis(Order - ss + 2, pp) ; 

            BsplineBasis(Order 
            - ss + 2, pp) *= - LocalInverse  ; 

            BsplineBasis(Order 
            - ss + 2, pp) +=   BsplineBasis(Order - ss + 2,qq) ; 

            BsplineBasis(Order 
            - ss + 2,qq) = Saved ; 







              FINISH : 

            return (ReturnCode) ; 




            函數(shù)的作用是用來計(jì)算所有的基函數(shù)及其導(dǎo)數(shù),并將結(jié)果以矩陣(數(shù)組)的形式保存。結(jié)合二次基函數(shù)的推導(dǎo)方法,將述代碼寫成公式的形式。函數(shù)的參數(shù)及其描述如下表所示:

            變量

            描述

            DerivativeRequest

            導(dǎo)數(shù)的次數(shù)

            Order

            B樣條基函數(shù)的階數(shù)(次數(shù)+1)

            FlatKnots

            節(jié)點(diǎn)矢量

            Parameter

            參數(shù)

            FirstNonZeroBspline

            第一個(gè)非零基函數(shù)的索引值

            BsplineBasis

            基函數(shù)值矩陣


            當(dāng)導(dǎo)數(shù)次數(shù)DerivativeRequest大于B樣條基的階數(shù)Order時(shí),將計(jì)算導(dǎo)數(shù)的次數(shù)設(shè)置為B樣條基的次數(shù)(Order-1)。程序代碼如下所示:

             

              LocalRequest = DerivativeRequest ; 

            if (DerivativeRequest >= Order) { 

                LocalRequest 
            = Order - 1 ; 


             

            對(duì)B樣條基數(shù)計(jì)算結(jié)果矩陣BsplineBasis存儲(chǔ)空間進(jìn)行檢查。若存儲(chǔ)空間不足,則會(huì)退出,程序代碼如下所示:

             

            if (BsplineBasis.LowerCol() != 1 || 

                  BsplineBasis.UpperCol() 
            < Order || 

                  BsplineBasis.LowerRow() 
            != 1 || 

                  BsplineBasis.UpperRow() 
            <= LocalRequest) { 

                ReturnCode 
            = 1

            goto FINISH ; 


             

            確定參數(shù)Parameter所在的節(jié)點(diǎn)區(qū)間的下標(biāo)(索引值),程序代碼如下所示:

             

            NumPoles = FlatKnots.Upper() - FlatKnots.Lower() + 1 - Order ; 

              BSplCLib::LocateParameter(Order 
            - 1

                FlatKnots, 

                Parameter, 

                Standard_False, 

                Order, 

                NumPoles
            +1

                ii, 

                            NewParameter) ; 


            確定參數(shù)Parameter所在區(qū)間的算法是用二分法搜索得到。程序代碼如下所示:

             

            //======================================================================= 

            //function : Hunt 

            //purpose  :  

            //======================================================================= 

            void BSplCLib::Hunt (const Array1OfReal& XX, 

            const Standard_Real X, 

                 Standard_Integer
            &   Ilc) 



            // replaced by simple dichotomy (RLE) 

              Ilc 
            = XX.Lower(); 

            const Standard_Real *px = &XX(Ilc); 

              px 
            -= Ilc; 

            if (X < px[Ilc]) { 

                Ilc
            --

            return



              Standard_Integer Ihi 
            = XX.Upper(); 

            if (X > px[Ihi]) { 

                Ilc 
            = Ihi + 1

            return



              Standard_Integer Im; 

            while (Ihi - Ilc != 1) { 

                Im 
            = (Ihi + Ilc) >> 1

            if (X > px[Im]) Ilc = Im; 

            else            Ihi = Im; 






            確定參數(shù)所在區(qū)間[ui,ui+1)后,可得到第一個(gè)非零基函數(shù)的索引值為i-p;

              FirstNonZeroBsplineIndex = ii - Order + 1 ;

            基函數(shù)計(jì)算的主要算法代碼如下所示:

             

            BsplineBasis(1,1= 1.0e0 ; 

            for (qq = 2 ; qq <= Order - LocalRequest ; qq++) { 

                BsplineBasis(
            1,qq) = 0.0e0 ; 

            for (pp = 1 ; pp <= qq - 1 ; pp++) { 

            // 

            // this should be always invertible if ii is correctly computed  

            // 

                  Factor 
            = (Parameter - FlatKnots(ii - qq + pp + 1)) 

            / (FlatKnots(ii + pp) - FlatKnots(ii - qq + pp + 1)) ; 

                  Saved 
            = Factor *    BsplineBasis(1,pp) ; 

                  BsplineBasis(
            1,pp) *= (1.0e0 - Factor) ; 

                  BsplineBasis(
            1,pp) += BsplineBasis(1,qq) ; 

                  BsplineBasis(
            1,qq) = Saved ; 






            其中:

            wps_clip_image-13697為節(jié)點(diǎn)區(qū)間[ui,ui+1)上的基函數(shù)左邊部分的系數(shù);

            wps_clip_image-7128為節(jié)點(diǎn)區(qū)間[ui-1,ui)上的基函數(shù)右邊部分的系數(shù);

             

            六、 程序示例 Sample Codes

            將上述內(nèi)容以一個(gè)簡(jiǎn)單示例程序來驗(yàn)證,程序代碼如下所示:

             

            /* 

            *    Copyright (c) 2013 eryar All Rights Reserved. 



            *        File    : Main.cpp 

            *        Author  : eryar@163.com 

            *        Date    : 2013-03-09 

            *        Version :  



            *    Description : Learn the B-Spline Curve library in the Open Cascade. 

            *                   

            */ 

            #include 
            <BSplCLib.hxx> 

            #include 
            <math_Matrix.hxx> 

            #include 
            <TColStd_Array1OfReal.hxx> 

            #include 
            <TColStd_Array1OfInteger.hxx> 

            #include 
            <Geom2d_BSplineCurve.hxx> 

            #pragma comment(lib, 
            "TKernel.lib"

            #pragma comment(lib, 
            "TKMath.lib"

            #pragma comment(lib, 
            "TKG2d.lib"

            int main(int argc, char* argv[]) 



            // Knot vector: [0,0,0,1,2,3,4,4,5,5,5] 

            TColStd_Array1OfReal knotSeq(
            111); 

                knotSeq.Init(
            0); 

                knotSeq.SetValue(
            10); 

                knotSeq.SetValue(
            20); 

                knotSeq.SetValue(
            30); 

                knotSeq.SetValue(
            41); 

                knotSeq.SetValue(
            52); 

                knotSeq.SetValue(
            63); 

                knotSeq.SetValue(
            74); 

                knotSeq.SetValue(
            84); 

                knotSeq.SetValue(
            95); 

                knotSeq.SetValue(
            105); 

                knotSeq.SetValue(
            115); 

                cout
            <<"Knot Sequence: [ "

            for (Standard_Integer i = 1; i <= knotSeq.Length(); i++



                    cout
            <<knotSeq.Value(i)<<" "



                cout
            <<"]"<<endl; 

                Standard_Integer knotsLen 
            = BSplCLib::KnotsLength(knotSeq); 

                TColStd_Array1OfReal knots(
            1, knotsLen); 

                TColStd_Array1OfInteger mults(
            1, knotsLen); 

            // Test Knots, Mults and Knot sequence of BSplCLib. 

            BSplCLib::Knots(knotSeq, knots, mults); 

                cout
            <<"Knots: [ "

            for (Standard_Integer i = 1; i <= knots.Length(); i++



                    cout
            <<knots.Value(i)<<" "



                cout
            <<"]"<<endl; 

                cout
            <<"Multiplicity: [ "

            for (Standard_Integer i = 1; i <= mults.Length(); i++



                    cout
            <<mults.Value(i)<<" "



                cout
            <<"]"<<endl; 

            if (BSplCLib::KnotForm(knots, 1, knotsLen) == BSplCLib_Uniform) 



                    cout
            <<"Knots is uniform."<<endl; 



            else 



                    cout
            <<"Knots is non-uniform."<<endl; 



                Standard_Real rValue 
            = 2.5

                Standard_Integer iOrder 
            = 2+1

                Standard_Integer iFirstNonZeroIndex 
            = 0

                math_Matrix bSplineBasis(
            111, iOrder, 0); 

                BSplCLib::EvalBsplineBasis(
            10, iOrder, knotSeq, rValue, iFirstNonZeroIndex, bSplineBasis); 

                cout
            <<"First Non-Zero Basis index: "<<iFirstNonZeroIndex<<endl; 

                cout
            <<bSplineBasis<<endl; 

            return 0




            上述代碼對(duì)節(jié)點(diǎn)矢量、重復(fù)度的概念的驗(yàn)證,并以一個(gè)實(shí)例計(jì)算所有非零基函數(shù)的值。程序輸出為:

            Knot Sequence: [ 0 0 0 1 2 3 4 4 5 5 5 ]

            Knots: [ 0 1 2 3 4 5 ]

            Multiplicity: [ 3 1 1 1 2 3 ]

            Knots is uniform.

            First Non-Zero Basis index: 3

            math_Matrix of RowNumber = 1 and ColNumber = 3

            math_Matrix ( 1, 1 ) = 0.125

            math_Matrix ( 1, 2 ) = 0.75

            math_Matrix ( 1, 3 ) = 0.125

            Press any key to continue . . .

             

            七、 結(jié)論 Conclusion

            通過學(xué)習(xí)《The NURBS Book》并給合Open Cascade的源程序,理論聯(lián)系實(shí)際,使對(duì)NURBS的學(xué)習(xí)更輕松。

            根據(jù)B樣條基的遞推公式,B樣條曲線的局部性是通過節(jié)點(diǎn)來具體實(shí)現(xiàn)的。與Bezier曲線不同的就是增加了節(jié)點(diǎn)這個(gè)參數(shù)。根據(jù)Cox-deBoor遞推公式親自推導(dǎo)出一次、二次、三次B樣條基函數(shù),可以加深對(duì)B樣條曲線的理解。

            計(jì)算給定節(jié)點(diǎn)矢量、次數(shù)及參數(shù),計(jì)算參數(shù)所在區(qū)間上所有非零基函數(shù)算法的步驟為:

            l 通過二分法查找出參數(shù)所在的節(jié)點(diǎn)區(qū)間;

            l 根據(jù)B樣條基的局部支撐性,計(jì)算出所在節(jié)點(diǎn)區(qū)間上所有非零基函數(shù);

             

            八、 致謝 Acknowledgments

            感謝曉天的支持與鼓勵(lì)。

             

            九、 參考文獻(xiàn) Bibliography

            1. 趙罡,穆國(guó)旺,王拉柱譯Les Piegl,Wayne Tiller The NURBS Book(Second Edition) 2010 清華大學(xué)出版社

            2. 莫容,常智勇 計(jì)算機(jī)輔助幾何造型技術(shù) 2009 科學(xué)出版社

            3. 王仁宏,李崇君,朱春鋼 計(jì)算幾何教程 2008 科學(xué)出版社

             

            Feedback

            # re: B-Spline Curve Library in Open Cascade  回復(fù)  更多評(píng)論   

            2013-03-13 05:28 by http://essay-writing-site.co.uk
            So nice grest so nice well done!
            国产精品gz久久久| 97久久综合精品久久久综合| 国产精品无码久久四虎| 无码人妻精品一区二区三区久久 | 亚洲精品WWW久久久久久| 久久综合色区| 久久久精品国产亚洲成人满18免费网站| 婷婷综合久久中文字幕| 亚洲欧美成人久久综合中文网| 亚洲中文字幕无码久久2020| 久久久久久国产精品免费免费 | 亚洲色大成网站WWW久久九九| 久久亚洲精品无码观看不卡| 国产成人精品综合久久久| 久久久久国产亚洲AV麻豆| 久久亚洲综合色一区二区三区| 亚洲国产精品久久电影欧美| 久久久久女人精品毛片| 99久久无色码中文字幕人妻 | 久久免费精品一区二区| 少妇精品久久久一区二区三区| 久久婷婷色香五月综合激情| 久久99久久99小草精品免视看 | 狠狠人妻久久久久久综合蜜桃| 狠狠88综合久久久久综合网| 久久精品国产99国产精品亚洲| 亚洲国产高清精品线久久| 狠狠色丁香婷婷久久综合| 日本WV一本一道久久香蕉| 久久久久久精品无码人妻| www久久久天天com| 人妻中文久久久久| 久久精品国产亚洲AV麻豆网站| 精品久久久久久无码国产| 欧美激情精品久久久久久久九九九| 久久婷婷五月综合成人D啪| 成人综合久久精品色婷婷| 18岁日韩内射颜射午夜久久成人| 国产日韩久久免费影院| 99久久人妻无码精品系列| 国产精品成人久久久|