• <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ézier Curve

            Posted on 2011-11-20 15:18 eryar 閱讀(4462) 評論(0)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

            在產品零件設計中,許多自由曲面是通過自由曲線來構造的。對于自由曲線的設計,設計人員經常需要大致勾畫出曲線的形狀,用戶希望有一種方法能不再采用一般的代數描述,而采用直觀的具有明顯幾何意義的操作,使得設計的曲線能夠逼近曲線的形狀。采用插值方法,用戶設計的曲線形狀不但受曲線上型值點的約束,而且受到邊界條件影響,用戶不能靈活調整曲線形狀。但在產品設計中,曲線的設計是經過多次修改和調整來完成的,已有的方法完成這樣的功能并不容易。Bézier方法的出現改善了上述設計方法的不足,使用戶能方便地實現曲線形狀的修改。

            一、Bézier曲線定義

            1. 定義:用基函數表示的Bézier曲線為

            clip_image002 clip_image004

            Bernstein基函數:

            clip_image006

            N=3時,即特征多邊形有四個頂點,由上式可得到三次Bernstein基函數:

            clip_image008

            因此根據定義可把三次Bézier曲線表示為:

            clip_image010

            也可根據上式寫成矩陣形式,有點類似二次型:

            clip_image012

            由上可知,只要給定特征多邊形的四個頂點矢量P0P1P2P3,并得用上式即可構造一條三次Bézier曲線。只要改變t值即可計算曲線上的點。對于曲線設計來說,采用這種特征多邊形頂點的方法比較方便、直觀。

            二、編程實現

            利用OpenGL的glut庫根據Bézier曲線定義來實現曲線的繪制,源程序如下:


            程序運行結果如圖1所示:

            Bezier Curve by definition

            圖1 根據定義實現的Bézier曲線

            可修改特征多邊形頂點變量controlPoint來看看相應的Bézier曲線的變化。

            三、Bézier曲線的遞推算法

            計算Bézier曲線上的點,可用Bézier曲線方程直接計算,但使用de Casteljau提出的遞推算法則要簡單得多。

            Bézier曲線的Bernstein基函數的遞推性質

            clip_image002[4]

            由于組合數的遞推性:

            clip_image004[4]

            因此有

            clip_image006[4]

            為了保證公式可計算,我們約定:在以上公式中,凡當指標超出范圍,以至記號不具有意義時,都應理解為零,如:

            clip_image008[4]

            根據Bézier曲線定義可知:

            clip_image010[4]

            這說明一條n次Bézier曲線可表示為分別由前后n個控制頂點決定的兩條n-1次Bézier曲線的線性組合。由此可得Bézier曲線上某一點遞歸求值的de Casteljau算法:

            clip_image012[4]

            其中:

            ——clip_image014, 是定義Bézier曲線的控制點;

            ——clip_image016,即是曲線P(t)上具有參數t的點;

            用這一遞推公式在給定參數下,求Bézier曲線上一點P(t)非常有效。de Casteljau算法穩定可靠,直觀簡便,可以編寫出十分簡捷的程序,是計算Bézier曲線的基本算法和標準算法。

            四、de Casteljau算法的程序實現

            根據遞推公式可寫出Bézier曲線的遞歸算法,如下:

            /*
            */
            Point    PointOnBezierCurve(int i, int k, float t) {
                if (k == 0) {
                    return ctrlPoint[i];
                }
                else {
                    Point    point;
                    Point    iPrev    =    PointOnBezierCurve(i, k-1, t);
                    Point    iNext    =    PointOnBezierCurve(i+1, k-1, t);
            
                    point.x    =    (1.0 - t) * iPrev.x + t * iNext.x;
                    point.y    =    (1.0 - t) * iPrev.y + t * iNext.y;
            
                    return point;
                }
            } // PointOnBezierCurve
            .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

            其中,為了保存數據的方便,控制頂點數組變量ctrlPoint為全局變量。

            根據遞推算法實現Bézier曲線與根據定義實現的程序效果如下圖2所示:

            Bezier Curve Comparation

            圖2 圖中上面部分為用遞推算法實現,下面部分為用定義實現。

            源程序如下:

            // Bezier Curve Program

            // File : BezierCurve.cpp

            #include <gl\glut.h>

            #define POINTS_NUM 100

            // point structure

            typedef struct SPoint{

            float x;

            float y;

            }Point;

            Point ctrlPoint[4]; // control point for recursive algorithm Bezier Curve

            void Initialize(void);

            void DrawScene(void);

            void myReshape(GLsizei w, GLsizei h);

            void PlotBezierCurveDirectly(void);

            Point PointOnBezierCurve(int i, int k, float t);

            void PlotBezierCurve(void);

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

            glutInit(&argc, argv); // Initialize GLUT

            glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); // Set display mode

            glutInitWindowPosition(50,100); // Set top-left display window position

            glutInitWindowSize(400, 300); // set display window width and height

            glutCreateWindow("Bézier Curve"); // Create display window

            Initialize(); // Execute initialization procedure

            glutDisplayFunc(DrawScene); // Send graphics to display window

            glutReshapeFunc(myReshape); //

            glutMainLoop(); // Display everything and wait

            }

            /*

            */

            void Initialize(void) {

            //glClearColor(1.0, 1.0, 1.0, 0.0); // Set Display-window color to white

            glMatrixMode(GL_PROJECTION); // Set projection parameters

            glLoadIdentity();

            gluOrtho2D(0.0, 200, 0.0, 150); //

            } // Initialize

            /*

            */

            void myReshape(GLsizei w, GLsizei h) {

            // Reset viewport and projection parameter

            glViewport(0, 0, w, h);

            glMatrixMode(GL_PROJECTION);

            glLoadIdentity();

            gluOrtho2D(0, w, 0, h);

            glMatrixMode(GL_MODELVIEW);

            } // myReshape

            /*

            */

            void DrawScene(void) {

            glClear(GL_COLOR_BUFFER_BIT); // Clear display window

            PlotBezierCurveDirectly();

            PlotBezierCurve();

            glFlush(); // Process all OpenGL routines as quickly possible

            } // DrawScene

            /*

            plot the Bezier Curve according to Definition.

            */

            void PlotBezierCurveDirectly(void) {

            // Basis functions

            #define B0(t) ((1.0 - t) * (1.0 - t) * (1.0 - t))

            #define B1(t) (3.0 * t * (1.0 - t) * (1.0 - t))

            #define B2(t) (3.0 * t * t * (1.0 - t))

            #define B3(t) (t * t * t)

            // initialize control points

            Point controlPoint[4];

            Point plotPoint[POINTS_NUM];

            controlPoint[0].x = 100.0;

            controlPoint[0].y = 100.0;

            controlPoint[1].x = 300.0;

            controlPoint[1].y = 200.0;

            controlPoint[2].x = 400.0;

            controlPoint[2].y = 200.0;

            controlPoint[3].x = 600.0;

            controlPoint[3].y = 100.0;

            // calculate the points on the Bezier curve

            glColor3f(1.0, 0.0, 0.0f); // set line segment geometry color to red

            glBegin(GL_LINE_STRIP);

            for (int i = 0; i < POINTS_NUM; ++i) {

            float t = 1.0 * i / POINTS_NUM;

            plotPoint[i].x = (B0(t) * controlPoint[0].x) +

            (B1(t) * controlPoint[1].x) +

            (B2(t) * controlPoint[2].x) +

            (B3(t) * controlPoint[3].x);

            plotPoint[i].y = (B0(t) * controlPoint[0].y) +

            (B1(t) * controlPoint[1].y) +

            (B2(t) * controlPoint[2].y) +

            (B3(t) * controlPoint[3].y);

            glVertex2f(plotPoint[i].x, plotPoint[i].y);

            }

            glEnd();

            // draw control points

            glColor3f(1.0, 1.0, 0.0f);

            glPointSize(6.0);

            glBegin(GL_POINTS);

            glVertex2f(controlPoint[0].x, controlPoint[0].y);

            glVertex2f(controlPoint[1].x, controlPoint[1].y);

            glVertex2f(controlPoint[2].x, controlPoint[2].y);

            glVertex2f(controlPoint[3].x, controlPoint[3].y);

            glEnd();

            // draw control polygon

            glColor3f(1.0, 0.0, 1.0f);

            glBegin(GL_LINE_STRIP);

            glVertex2f(controlPoint[0].x, controlPoint[0].y);

            glVertex2f(controlPoint[1].x, controlPoint[1].y);

            glVertex2f(controlPoint[2].x, controlPoint[2].y);

            glVertex2f(controlPoint[3].x, controlPoint[3].y);

            glEnd();

            } // PlotBezierCurveDirectly

            /*

            */

            Point PointOnBezierCurve(int i, int k, float t) {

            if (k == 0) {

            return ctrlPoint[i];

            }

            else {

            Point point;

            Point iPrev = PointOnBezierCurve(i, k-1, t);

            Point iNext = PointOnBezierCurve(i+1, k-1, t);

            point.x = (1.0 - t) * iPrev.x + t * iNext.x;

            point.y = (1.0 - t) * iPrev.y + t * iNext.y;

            return point;

            }

            } // PointOnBezierCurve

            /*

            Use recursive algorithm to plot Bezier Curve.

            */

            void PlotBezierCurve(void) {

            // initialize control points

            ctrlPoint[0].x = 100.0;

            ctrlPoint[0].y = 300.0;

            ctrlPoint[1].x = 300.0;

            ctrlPoint[1].y = 400.0;

            ctrlPoint[2].x = 400.0;

            ctrlPoint[2].y = 400.0;

            ctrlPoint[3].x = 600.0;

            ctrlPoint[3].y = 300.0;

            Point plotPoint[POINTS_NUM];

            // calculate the points on the Bezier curve

            glColor3f(1.0, 0.0, 0.0f); // set line segment geometry color to red

            glBegin(GL_LINE_STRIP);

            for (int i = 0; i < POINTS_NUM; ++i) {

            float t = 1.0 * i / POINTS_NUM;

            plotPoint[i] = PointOnBezierCurve(0,3,t);

            glVertex2f(plotPoint[i].x, plotPoint[i].y);

            }

            glEnd();

            // draw control points

            glColor3f(1.0, 1.0, 1.0f);

            glPointSize(6.0);

            glBegin(GL_POINTS);

            glVertex2f(ctrlPoint[0].x, ctrlPoint[0].y);

            glVertex2f(ctrlPoint[1].x, ctrlPoint[1].y);

            glVertex2f(ctrlPoint[2].x, ctrlPoint[2].y);

            glVertex2f(ctrlPoint[3].x, ctrlPoint[3].y);

            glEnd();

            // draw control polygon

            glColor3f(0.0, 0.0, 1.0f);

            glBegin(GL_LINE_STRIP);

            glVertex2f(ctrlPoint[0].x, ctrlPoint[0].y);

            glVertex2f(ctrlPoint[1].x, ctrlPoint[1].y);

            glVertex2f(ctrlPoint[2].x, ctrlPoint[2].y);

            glVertex2f(ctrlPoint[3].x, ctrlPoint[3].y);

            glEnd();

            } // PlotBezierCurve

            因此,根據遞歸算法繪制Bézier曲線的程序簡單直觀,便于把數學公式與程序對應。

            Bezier Curve with different Control Points

            圖3 修改控制頂點后效果圖

            亚洲精品国精品久久99热| 东方aⅴ免费观看久久av| 91精品国产高清久久久久久国产嫩草| 欧美久久天天综合香蕉伊| 久久综合丝袜日本网| 2021精品国产综合久久| 亚洲国产精品无码久久98| 一极黄色视频久久网站| 久久久久女人精品毛片| 欧美黑人又粗又大久久久| 久久精品国产AV一区二区三区| 欧美亚洲国产精品久久久久| 久久精品18| 亚洲精品午夜国产va久久| 国产99久久精品一区二区| 亚洲国产天堂久久久久久| 国产成人精品久久二区二区| 久久久久99这里有精品10| 99热精品久久只有精品| 久久99精品国产99久久6| 久久久久这里只有精品| 国产亚州精品女人久久久久久| 狠狠综合久久综合88亚洲| 久久国产视屏| 99国产精品久久| 亚洲日本va中文字幕久久| 欧美性猛交xxxx免费看久久久| 久久九九亚洲精品| AV狠狠色丁香婷婷综合久久| 国产—久久香蕉国产线看观看| 久久综合香蕉国产蜜臀AV| 日韩欧美亚洲综合久久| 久久福利青草精品资源站| 老司机午夜网站国内精品久久久久久久久| 77777亚洲午夜久久多人| 伊人久久大香线蕉综合网站| 久久天天躁狠狠躁夜夜2020 | 中文字幕成人精品久久不卡| 狠狠色婷婷久久一区二区三区 | 久久久久亚洲AV无码网站| 亚洲人成网亚洲欧洲无码久久 |