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

eryar

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

Polynomial Library in OpenCascade

Posted on 2013-05-08 22:50 eryar 閱讀(3772) 評論(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>
            欧美成人免费在线| 久久人91精品久久久久久不卡 | 一区二区三区欧美激情| 亚洲三级影片| 欧美激情综合五月色丁香| 99精品国产福利在线观看免费| 亚洲人成在线观看| 国产精品v欧美精品v日本精品动漫 | 亚洲电影在线看| 亚洲第一二三四五区| 欧美噜噜久久久xxx| 亚洲欧美在线视频观看| 久久国内精品自在自线400部| 亚洲二区视频| 一区二区三区欧美在线| 黑人巨大精品欧美一区二区小视频| 老色鬼久久亚洲一区二区 | 欧美一区二区三区成人| 亚洲国产另类久久精品| 一区二区三区鲁丝不卡| 黄色精品一区二区| 亚洲毛片在线| 影音先锋中文字幕一区| 99re热精品| 亚洲国产精品久久| 亚洲一区日本| 亚洲三级电影全部在线观看高清| 亚洲欧美大片| av成人激情| 久久免费高清| 性欧美激情精品| 欧美日韩岛国| 你懂的网址国产 欧美| 国产精品久久久久久超碰| 亚洲高清一二三区| 国一区二区在线观看| 日韩视频亚洲视频| 亚洲国产欧美在线人成| 香蕉尹人综合在线观看| 亚洲午夜国产一区99re久久 | 一区二区高清在线| 亚洲欧洲在线观看| 久久久在线视频| 欧美一级理论片| 欧美亚洲成人精品| 亚洲精品久久嫩草网站秘色| 在线免费观看一区二区三区| 欧美在线影院| 久久成人羞羞网站| 国产免费亚洲高清| 亚洲一区二区在线观看视频| 亚洲视频在线观看| 欧美日韩免费在线观看| 亚洲精品一区在线观看香蕉| 亚洲毛片在线| 欧美激情精品久久久久久黑人| 麻豆精品在线视频| 伊人春色精品| 久久夜色精品国产| 老司机精品视频网站| 狠狠爱综合网| 麻豆freexxxx性91精品| 女仆av观看一区| 亚洲国产精品久久| 欧美激情网站在线观看| 亚洲激情社区| 一区二区三区视频在线播放| 欧美高清在线视频| 日韩视频免费大全中文字幕| 中文有码久久| 国产精品久久久久久户外露出| 在线视频精品一区| 欧美一区二区日韩一区二区| 国产一区在线免费观看| 久久精品国产免费| 欧美激情自拍| 亚洲视频播放| 国产视频久久久久久久| 久久久久88色偷偷免费| 欧美高清视频在线播放| 99精品视频免费观看视频| 欧美日韩在线观看一区二区三区| 这里只有精品电影| 久久精品视频在线| 亚洲精品色图| 国产精品九九久久久久久久| 香蕉久久夜色精品国产使用方法| 久久在线视频在线| 夜夜躁日日躁狠狠久久88av| 国产美女精品视频| 免费在线成人av| 中文精品视频| 免费视频亚洲| 亚洲免费人成在线视频观看| 狠狠色噜噜狠狠狠狠色吗综合| 欧美岛国激情| 欧美一区二区三区四区高清 | 亚洲婷婷综合久久一本伊一区| 久久久久一区| 99热这里只有精品8| 国产色产综合色产在线视频| 欧美精品久久久久a| 午夜在线精品| 亚洲乱码国产乱码精品精天堂| 久久成人18免费观看| 日韩亚洲欧美综合| 黄色精品一二区| 国产精品久久久999| 久久一二三四| 亚洲欧美日韩中文在线制服| 亚洲激情视频在线播放| 久久久久久久波多野高潮日日| 一区二区三区四区蜜桃| 在线成人h网| 国产午夜精品视频| 欧美日韩中文字幕在线| 美女主播精品视频一二三四| 欧美一区二区三区精品| 9l国产精品久久久久麻豆| 欧美福利一区二区| 久久久av水蜜桃| 性色av一区二区三区| 一区二区三区视频在线播放| 亚洲日本激情| 影音先锋中文字幕一区| 国产一级久久| 国产视频欧美| 国产亚洲精品福利| 国产欧美日韩精品专区| 欧美特黄一级| 欧美日韩一本到| 欧美激情综合亚洲一二区| 免费成人黄色av| 蜜桃精品久久久久久久免费影院| 久久精品91| 欧美在现视频| 欧美伊人久久| 欧美一区二区三区视频| 欧美一区1区三区3区公司| 亚洲欧美综合精品久久成人| 亚洲免费影院| 亚洲欧美精品在线观看| 亚洲一区二区三区在线播放| 亚洲一区日韩在线| 欧美亚洲综合网| 久久免费精品日本久久中文字幕| 久久婷婷亚洲| 欧美丰满少妇xxxbbb| 欧美日韩18| 国产精品三级视频| 国产亚洲激情在线| 国产一区二区精品| 在线看欧美日韩| 亚洲久久成人| 亚洲在线第一页| 久久成年人视频| 欧美aaaaaaaa牛牛影院| 欧美国产精品劲爆| 日韩亚洲欧美精品| 亚洲尤物在线视频观看| 久久久精品日韩欧美| 欧美激情a∨在线视频播放| 欧美日韩影院| 国产婷婷色一区二区三区在线| 韩国视频理论视频久久| 亚洲国产婷婷香蕉久久久久久99| 99国产麻豆精品| 欧美一区二区三区精品| 麻豆精品网站| 亚洲裸体俱乐部裸体舞表演av| 亚洲永久网站| 欧美不卡视频一区| 国产美女精品视频| 亚洲精品午夜| 欧美一区二区三区喷汁尤物| 欧美激情1区2区3区| 在线亚洲伦理| 久久综合色播五月| 国产精品国产三级国产专区53 | 国产欧美日韩综合一区在线观看| 亚洲国产成人一区| 亚洲一区二区综合| 欧美成ee人免费视频| 中文亚洲视频在线| 免费观看在线综合色| 国产精品影片在线观看| 99re视频这里只有精品| 玖玖精品视频| 亚洲欧美成人一区二区在线电影 | 亚洲欧美精品中文字幕在线| 欧美黑人多人双交| 国产一区二区三区在线观看网站| 日韩天堂在线视频| 免播放器亚洲一区| 亚洲男人第一av网站| 欧美日韩另类一区| 亚洲日本在线观看| 欧美暴力喷水在线| 久久久久久久激情视频| 国产精品综合av一区二区国产馆|