青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

eryar

PipeCAD - Plant Piping Design Software.
PlantAssistant - Translate AVEVA RVM/SP3D VUE to glTF, STEP, etc.
posts - 606, comments - 590, trackbacks - 0, articles - 0

Polynomial Library in OpenCascade

Posted on 2013-05-08 22:50 eryar 閱讀(3777) 評論(0)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

Polynomial Library in OpenCascade

eryar@163.com

摘要Abstract:分析冪基曲線即多項式曲線在OpenCascade中的計算方法,以及利用OpenSceneGraph來顯示OpenCascade的計算結果,加深對多項式曲線的理解。

關鍵字Key Words:OpenCascade、PLib、OpenSceneGraph、Polynomial Library

 

一、 概述 Overview

CAGD(Computer Aided Geometry Design)中,基表示的參數矢函數形式已經成為形狀數學描述的標準形式。人們首先注意到在各類函數中,多項式函數(Polynomial Function)能較好地滿足要求。它表示形式簡單,又無窮次可微,且容易計算函數值及各階導數值。采用多項式函數作為基函數即多項式基,相應可以得到參數多項式曲線曲面。

人們很早就注意到這樣一個問題:設f(x)∈C[a,b],對于任意給的ε>0,是否存在這樣的多項式p(x),使得

wps_clip_image-32310

對一切a≤x≤b一致成立?

1885年,Weierstrass證明了p(x)的存在性;

1912年,Bernstein將滿足條件的多項式構造出來。

Weierstrass定理:設f(x)∈C[a,b],那么對于任意給的ε>0,都存在這樣的多項式p(x),使得

wps_clip_image-7708

Weierstrass定理說明,[a,b]上的任何連續函數都可以用多項式來一致逼近。該定理實際上正好解決了利用多項式組成的函數來表示連續函數的問題。

冪(又稱單項式monomial)基uj(j=0,1,,,n)是最簡單的多項式基。相應多項式的全體構成n次多項式空間。n次多項式空間中任一組n+1個線性無關的多項式都可以作為一組基,因此就有無窮多組基。不同組基之間僅僅相差一個線性變換。

如果允許坐標函數x(u),y(u),z(u)是任意的,則可以得到范圍很廣的曲線。但是在實際開發一個幾何造型系統時,我們需要一些折中,理想的情況是將坐標函數限制在滿足下述條件的一類函數中:

l 能夠精確地表示用戶需要的所有曲線;

l 在計算機中能夠被方便、高效、精確地處理,特別是可以高效地計算曲線上的點及各階導矢;函數的數值計算對浮點數舍入誤差不敏感;函數所需要的存儲量較小;

l 比較簡單,在數學上易于理解。

一類被廣泛使用的函數就是多項式。盡管它們滿足上標準中的后兩項,但有很多類型的重要曲線(及曲面)不能用多項式精確表示,在系統中,這些曲線只能用多項式逼近。同一參數多項式曲線可以采用不同的基表示,如冪基表示和Bezier表示,由些決定了它們具有不同的性質,因而就有不同的優點。

 

二、 冪基曲線的計算 Calculate Polynomial Function

一條n次曲線的冪基表示形式是:

wps_clip_image-11805,其中wps_clip_image-19121是矢量。

給定u0,計算冪基曲線上的點C(u0)的最有效算法是英國數學家W.G.Horner提出的Horner方法。Horner算法是遞歸概念的一個典型實例,它采用最少的乘法來進行多項式求值,使計算由X^n問題轉化為O(n)的問題。

l 當次數=1時:wps_clip_image-31777

l 當次數=2時:wps_clip_image-19321

l ……

l 當次數=n時:wps_clip_image-1762

用數組來直接計算:

 

 

 1 void Horner1(a, n, u0, C) 
 2 
 3     C = a[n]; 
 4 
 5     for (int i = n-1; i >= 0; i--
 6     { 
 7         C = C * u0 + a[i]; 
 8     } 
 9 
10 

 

在OpenSceneGraph中來計算:

 

 1 void Horner(osg::Vec3Array* a, double u, osg::Vec3& p)
 2 {
 3     int n = a->size() - 1;
 4     
 5     p = a->at(n);
 6 
 7     for (int i = n-1; i >= 0; i--)
 8     {
 9         p = p * u + a->at(i);
10     }
11 }


三、 冪基曲線的顯示 Render Power Basis Curve

利用Horner方法可以計算[0,1]區間上相應曲線上的點,將這些點連成線就構成了冪基曲線的近似表示。在OpenSceneGraph中顯示冪基曲線程序如下所示:

 

  1 /**
  2 *    Copyright (c) 2013 eryar All Rights Reserved.
  3 *
  4 *        File    : Main.cpp
  5 *        Author  : eryar@163.com
  6 *        Date    : 2013-05-06
  7 *        Version : 0.1
  8 *
  9 *    Description : PLib means Polynomial functions library.
 10 *       The PLib in occ provides basic computation functions
 11 *       for polynomial functions.
 12 *
 13 */
 14 
 15 // OpenSceneGraph
 16 #include <osg/Vec3>
 17 #include <osg/Array>
 18 #include <osg/Geode>
 19 #include <osg/Group>
 20 #include <osg/MatrixTransform>
 21 #include <osgGA/StateSetManipulator>
 22 #include <osgViewer/Viewer>
 23 #include <osgViewer/ViewerEventHandlers>
 24 
 25 #pragma comment(lib, "osgd.lib")
 26 #pragma comment(lib, "osgGAd.lib")
 27 #pragma comment(lib, "osgViewerd.lib")
 28 
 29 // OpenCascade
 30 #include <PLib.hxx>
 31 #include <TColgp_Array1OfPnt.hxx>
 32 #include <TColStd_Array1OfReal.hxx>
 33 
 34 #pragma comment(lib, "TKernel.lib")
 35 #pragma comment(lib, "TKMath.lib")
 36 
 37 /*
 38 * @breif Compute point on power basis curve.
 39 * @param [in] a: 
 40 * @param [in] x: 
 41 * @return: Point on power basis curve.
 42 */
 43 void Horner(osg::Vec3Array* a, double u, osg::Vec3& p)
 44 {
 45     int n = a->size() - 1;
 46 
 47     if (-1 == n)
 48     {
 49         return ;
 50     }
 51     
 52     p = a->at(n);
 53 
 54     for (int i = n-1; i >= 0; i--)
 55     {
 56         p = p * u + a->at(i);
 57     }
 58 }
 59 
 60 osg::Node* RenderPowerBasisCurve()
 61 {
 62     const int nStep = 100;
 63     osg::Geode* curveNode = new osg::Geode();
 64     osg::ref_ptr<osg::Geometry> curveGeom = new osg::Geometry();
 65     osg::ref_ptr<osg::Vec3Array> curvePnts = new osg::Vec3Array();
 66 
 67     // Test to compuate point on power basis curve.
 68     osg::ref_ptr<osg::Vec3Array> ctrlPnts = new osg::Vec3Array;
 69     ctrlPnts->push_back(osg::Vec3(006));
 70     ctrlPnts->push_back(osg::Vec3(306));
 71     ctrlPnts->push_back(osg::Vec3(603));
 72     //ctrlPnts->push_back(osg::Vec3(6, 0, 0));
 73 
 74     for (int i = 0; i < nStep; i++)
 75     {
 76         osg::Vec3 pnt;
 77         Horner(ctrlPnts, i * 1.0 / nStep, pnt);
 78 
 79         curvePnts->push_back(pnt);
 80     }
 81 
 82     curveGeom->setVertexArray(curvePnts);
 83     curveGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, curvePnts->size()));
 84 
 85     curveNode->addDrawable(curveGeom);
 86 
 87     return curveNode;
 88 }
 89 
 90 osg::Node* TestPLib(void)
 91 {
 92     const int nStep = 100;
 93     osg::Geode* curveNode = new osg::Geode();
 94     osg::ref_ptr<osg::Geometry> curveGeom = new osg::Geometry();
 95     osg::ref_ptr<osg::Vec3Array> curvePnts = new osg::Vec3Array();
 96 
 97     TColgp_Array1OfPnt poles(13);
 98     TColStd_Array1OfReal fp(1, poles.Length() * 3);
 99     TColStd_Array1OfReal points(013);
100 
101     Standard_Real* polynomialCoeff = (Standard_Real*&(fp(fp.Lower()));
102     Standard_Real* result = (Standard_Real*)&(points(points.Lower()));
103 
104     poles.SetValue(1, gp_Pnt(006));
105     poles.SetValue(2, gp_Pnt(306));
106     poles.SetValue(3, gp_Pnt(603));
107 
108     // Change poles to flat array.
109     PLib::SetPoles(poles, fp);
110 
111     // Three control point, so degree is 3-1=2.
112     Standard_Integer nDegree = 3 - 1;
113 
114     // Because point are 3 Dimension.
115     Standard_Integer nDimension = 3;
116 
117     for (int i = 0; i < nStep; i++)
118     {
119         PLib::NoDerivativeEvalPolynomial(
120         i * 1.0 / nStep, 
121         nDegree, 
122         nDimension,
123         nDegree * nDimension,
124         polynomialCoeff[0], 
125         result[0]);
126 
127         // 
128         curvePnts->push_back(osg::Vec3(result[0], result[1], result[2]));
129     }
130 
131     curveGeom->setVertexArray(curvePnts);
132     curveGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, curvePnts->size()));
133 
134     curveNode->addDrawable(curveGeom);
135 
136     return curveNode;
137 }
138 
139 int main(int argc, char* argv[])
140 {
141     osgViewer::Viewer myViewer;
142     osg::ref_ptr<osg::Group> root = new osg::Group();
143 
144     root->addChild(RenderPowerBasisCurve());
145 
146     // Translate along x axis.
147     osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform();
148     transform->setMatrix(osg::Matrix::translate(100));
149     transform->addChild(TestPLib());
150 
151     root->addChild(transform);
152 
153     myViewer.setSceneData(root);
154 
155     myViewer.addEventHandler(new osgGA::StateSetManipulator(myViewer.getCamera()->getOrCreateStateSet()));
156     myViewer.addEventHandler(new osgViewer::StatsHandler);
157     myViewer.addEventHandler(new osgViewer::WindowSizeHandler);
158 
159     return myViewer.run();
160 }
161 

 

設置不同的控制點ctrlPnts,就得到不同的曲線。

當n=1時,有兩個控制點a0, a1,表示由a0到a0+a1的直線段,如圖3.1所示:

wps_clip_image-6916

Figure 3.1 連接兩點(0,0,6)到(3,0,6)的直線

當n=2時,曲線是一段由a0到a0+a1+a2的拋物線弧,如圖3.2所示:

wps_clip_image-887

Figure 3.2 拋物線弧(0,0,6)(3,0,6)(6,0,3)

 

四、 occ中的多項式計算庫The PLib in OCC

在OpenCascade中的基礎模塊(FoundationClasses)的數學計算工具箱(TKMath Toolkit)中有個PLib包,用以對多項式進行基本的計算。PLib庫中的函數都是靜態函數,所以都是類函數,可以用類名加函數名直接調用。

PLib可對多項式進行如下計算:

l 計算多項式的值:EvalPolynomial;

l 計算Lagrange插值:EvalLagrange;

l 計算Hermite插值:EvalCubicHermite;

其中計算多項式值的方法也是用的Horner方法。

包PLib中提供了計算幾何的數學基礎中多項式插值中大部分插值計算。結合書籍《計算幾何教程》科學出版社中第一章的理論內容及OpenCascade的源程序,可以方便計算幾何的數學基礎知識的學習。

 

五、 使用PLib Apply PLib Class

因為包PLib中的類PLib都是靜態函數,所以函數傳入的參數比較多,若要使用這些計算函數,需要對其函數參數進行了解。為了對不同維數多項式進行計算,類PLib中把空間點轉換成了實數數組,并提供了相互轉換的函數。以計算多項式值為例,來說明使用PLib的方法。程序代碼如下所示:

 

 1 osg::Node* TestPLib(void)
 2 {
 3     const int nStep = 100;
 4     osg::Geode* curveNode = new osg::Geode();
 5     osg::ref_ptr<osg::Geometry> curveGeom = new osg::Geometry();
 6     osg::ref_ptr<osg::Vec3Array> curvePnts = new osg::Vec3Array();
 7 
 8     TColgp_Array1OfPnt poles(13);
 9     TColStd_Array1OfReal fp(1, poles.Length() * 3);
10     TColStd_Array1OfReal points(013);
11 
12     Standard_Real* polynomialCoeff = (Standard_Real*&(fp(fp.Lower()));
13     Standard_Real* result = (Standard_Real*)&(points(points.Lower()));
14 
15     poles.SetValue(1, gp_Pnt(006));
16     poles.SetValue(2, gp_Pnt(306));
17     poles.SetValue(3, gp_Pnt(603));
18 
19     // Change poles to flat array.
20     PLib::SetPoles(poles, fp);
21 
22     // Three control point, so degree is 3-1=2.
23     Standard_Integer nDegree = 3 - 1;
24 
25     // Because point are 3 Dimension.
26     Standard_Integer nDimension = 3;
27 
28     for (int i = 0; i < nStep; i++)
29     {
30         PLib::NoDerivativeEvalPolynomial(
31         i * 1.0 / nStep, 
32         nDegree, 
33         nDimension,
34         nDegree * nDimension,
35         polynomialCoeff[0], 
36         result[0]);
37 
38         // 
39         curvePnts->push_back(osg::Vec3(result[0], result[1], result[2]));
40     }
41 
42     curveGeom->setVertexArray(curvePnts);
43     curveGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, curvePnts->size()));
44 
45     curveNode->addDrawable(curveGeom);
46 
47     return curveNode;
48 }


函數PLib::SetPoles可以將空間坐標點轉換為實數數組。在調用無微分計算多項式的函數時,將坐標點的實數數組的首地址作為參數之一傳入。

為了與前面的Horner方法計算多項式的結果進行對比,將OpenCascade對相同點計算的結果也顯示出來。如下圖5.1所示:

wps_clip_image-13254

Figure 5.1 PLib compute result VS. Previous Horner method

由上圖可知,PLib的計算結果與前面的Horner方法計算結果相同。查看OpenCascade的源程序,得其多項式計算方法也是采用的Horner方法。

 

 1 void  PLib::NoDerivativeEvalPolynomial(const Standard_Real    Par, 
 2 
 3 const Standard_Integer Degree, 
 4 
 5 const Standard_Integer Dimension,  
 6 
 7 const Standard_Integer DegreeDimension,  
 8 
 9        Standard_Real&         PolynomialCoeff, 
10 
11        Standard_Real&         Results) 
12 
13 
14 
15   Standard_Integer jj; 
16 
17   Standard_Real *RA = &Results ;   
18 
19   Standard_Real *PA = &PolynomialCoeff ; 
20 
21   Standard_Real *tmpRA = RA; 
22 
23   Standard_Real *tmpPA = PA + DegreeDimension; 
24 
25 switch (Dimension) { 
26 
27 case 1 : { 
28 
29     *tmpRA = *tmpPA; 
30 
31 for (jj = Degree  ; jj >  0 ; jj--) { 
32 
33       tmpPA--
34 
35       *tmpRA = Par * (*tmpRA) + (*tmpPA); 
36 
37     } 
38 
39 break
40 
41   } 
42 
43 
44 
45 


從上述計算一維多項式的代碼可以看出,計算方法與前面的Horner方法相同。

 

六、 結論

學習使用Horner方法來計算多項式的值,并將計算結果在OpenSceneGraph中顯示。通過使用OpenCascade的多項式庫PLib來計算多項式的值,并結合其源程序來理解如何使用庫PLib。庫PLib為了統一多項式的計算,將空間點都轉換成數組后再進行計算,在這其中大量使用了指針,代碼可讀性也不是很好,需要仔細、耐心。

 

七、 參考資料

1. 王仁宏、李崇君、朱春鋼 計算幾何教程 科學出版社 2008.6

2. 趙罡、穆國旺、王拉柱 非均勻有理B樣條《The NURBS Book》 清華大學出版社 2010.12

3.  OpenCascade source code

 

PDF Version and Source Code: Polynomial Library in OpenCascade

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲国产精品精华液网站| 国内精品久久久久影院色| 亚洲高清色综合| 久久精品视频网| 黄色一区二区三区| 亚洲激情女人| 国产欧美一区二区精品秋霞影院 | 亚洲伦理一区| 亚洲国产一区二区精品专区| 亚洲无线视频| 欧美一级播放| 免费日韩av片| 亚洲一区www| 欧美国产一区二区三区激情无套| 一区二区不卡在线视频 午夜欧美不卡'| 99视频一区二区| 欧美另类变人与禽xxxxx| 久久高清福利视频| 国产欧美精品一区二区三区介绍 | 妖精成人www高清在线观看| aaa亚洲精品一二三区| 国产精品尤物福利片在线观看| 亚洲免费在线| 亚洲巨乳在线| 欧美成ee人免费视频| 精品不卡视频| 欧美在线播放视频| 日韩一区二区免费高清| 亚洲国产小视频| 欧美理论电影网| 麻豆av福利av久久av| 91久久国产综合久久蜜月精品| 久久伊人精品天天| 久久尤物电影视频在线观看| 尤物精品在线| 欧美成人午夜影院| 欧美成人69av| 亚洲国产美国国产综合一区二区| 欧美亚洲一区| 久久综合久久综合久久综合| 午夜精品久久久久久久白皮肤| 中国成人黄色视屏| 久久综合九色综合欧美就去吻 | 亚洲国语精品自产拍在线观看| 欧美午夜理伦三级在线观看| 久久综合久久久| 亚洲私人影院在线观看| 亚洲午夜激情在线| 欧美一区二粉嫩精品国产一线天| 亚洲桃色在线一区| 韩国久久久久| 国产精品成人aaaaa网站| 欧美精品一区在线发布| 亚洲淫性视频| 在线日韩视频| 亚洲精选在线| 亚洲综合精品| 久久午夜精品一区二区| 亚洲第一级黄色片| 久久精品中文字幕免费mv| 在线视频欧美精品| 黄色成人精品网站| 亚洲高清在线| 在线中文字幕日韩| 国产精品美女在线观看| 欧美精品一区二区在线播放| 国产日韩一级二级三级| 国产精品毛片va一区二区三区 | 久久久国产午夜精品| 亚洲午夜精品视频| 久久精品国产亚洲5555| 久久精品女人的天堂av| 欧美日韩精品三区| 影院欧美亚洲| 夜久久久久久| 一区二区三区精密机械公司| 亚洲精品国精品久久99热| 亚洲尤物视频网| 欧美一区二区三区的| 在线精品国产成人综合| 亚洲欧洲另类国产综合| 亚洲欧美成人一区二区三区| 国产精品免费一区豆花| 亚洲欧美在线一区| 极品中文字幕一区| 亚洲国产99| 亚洲国产黄色片| 久久国产精品高清| 国产精品久久久久久久久果冻传媒| 国产一区观看| 久久网站免费| 鲁大师影院一区二区三区| 国产亚洲一区二区三区| 久久久久天天天天| 一区二区成人精品| 欧美成人午夜剧场免费观看| 国内外成人免费视频| 午夜欧美不卡精品aaaaa| 99精品黄色片免费大全| 欧美激情亚洲一区| 一本色道久久综合亚洲精品不卡| 一本色道久久| 国内成人在线| 最新国产成人av网站网址麻豆| 老鸭窝91久久精品色噜噜导演| 国产欧美一区二区精品忘忧草| 夜夜嗨av一区二区三区| 国产欧美日韩激情| 亚洲国产精品久久91精品| 久久精品亚洲热| 久久久久国产一区二区三区| 欧美大片在线观看| 亚洲成人在线网| av不卡在线| 99在线|亚洲一区二区| 午夜精品视频在线观看一区二区| 国产精品久久久免费| 一本一本a久久| 欧美激情bt| 国产精品亚洲一区| 红桃视频欧美| 欧美成年人网站| 日韩一区二区精品视频| 亚洲精品女人| 亚洲欧洲三级| 国产精品亚洲美女av网站| 国产精品qvod| 欧美三级韩国三级日本三斤| 欧美巨乳在线| 国产精品久久久久久久久搜平片| 欧美视频一区二区三区…| 国产一区二区三区在线免费观看| 国产欧美一区二区精品忘忧草| 在线免费观看视频一区| 亚洲第一综合天堂另类专| 亚洲视频在线观看一区| 欧美一区二区久久久| 亚洲啪啪91| 亚洲国产精品一区二区三区| 久久国产精品一区二区| 老司机精品视频一区二区三区| 午夜精品久久久久久久久久久久 | 国产精品丝袜久久久久久app| 欧美刺激午夜性久久久久久久| 中文无字幕一区二区三区| 乱中年女人伦av一区二区| 国产精品99久久久久久久vr| 99国产一区二区三精品乱码| 一区二区三区四区五区精品视频| 91久久精品久久国产性色也91| 在线成人免费视频| 91久久国产自产拍夜夜嗨| 伊人久久av导航| 亚洲日韩中文字幕在线播放| 亚洲美女黄网| 午夜精品久久久久久久蜜桃app| 欧美激情一区二区三区成人| 羞羞色国产精品| 牛牛国产精品| 国产日韩欧美| 亚洲一区二区三区成人在线视频精品| 亚洲午夜未删减在线观看| 在线中文字幕一区| 亚洲女人天堂av| 欧美成人蜜桃| 亚洲影院污污.| 免费在线观看日韩欧美| 欧美午夜欧美| 亚洲免费成人av| 久久人人爽国产| 99日韩精品| 欧美精品一区二区蜜臀亚洲| 国产日产欧产精品推荐色| 欧美在线视频观看免费网站| 一本色道久久综合精品竹菊| 欧美v国产在线一区二区三区| 亚洲韩国一区二区三区| 亚洲精品久久久久久久久| 亚洲综合激情| 一本色道久久99精品综合| 久久精品视频免费| 国产欧美日本| 欧美一区二区免费观在线| 亚洲欧美综合一区| 亚洲视频自拍偷拍| 久久久精彩视频| 亚洲欧美精品中文字幕在线| 欧美精品九九| 欧美一区二区三区在线观看视频| 欧美影院视频| 亚洲电影毛片| 欧美一区不卡| 国产一区二区日韩精品| 一区二区激情| 欧美精品一区二区三区视频| 欧美亚洲免费电影| 一本一本久久a久久精品综合妖精| 国产亚洲精品成人av久久ww| 欧美视频不卡| 欧美视频在线观看免费网址|