分享

使用OpenGL绘制Bezier曲线

 Bookroom for JetYang 2023-10-05 发布于湖南

Bezier曲线的数学表达

这是普通三次多项式曲线的参数表达式:

这是贝塞尔曲线的参数表达式:(可以上下参照记忆)

 

 

 用C语言实现Bezier曲线的绘制


我们采用逼近的手法达到近似的效果,通过程序计算出多个p(u),并用直线连接相邻两个点

以下代码转自(46条消息) 图形算法:贝塞尔曲线_陈小默的博客-CSDN博客_贝塞尔曲线算法

#include<GL/glut.h>#include<math.h>
复制代码
typedef struct {    int length;    int* arr;
}intArray;//系数坐标typedef struct {    float x, y,z;
} point3D;//存储二维坐标typedef struct {    int length;
    point3D* arr;
}pointArray;
pointArray ctrlPts_;
 
复制代码
复制代码
//计算二项式系数
//接受一个数组对象的引用void binomialCoefficient(intArray& Cin) {    int j, n = Cin.length - 1;    for (int k = 0; k <= n; k++) {//计算n+1个二项式系数
        Cin.arr[k] = 1;//初始化
        for (j = n; j > n-k; j--) {  
            Cin.arr[k] *= j;//连乘        }        for (j = k; j > 1; j--) {
            Cin.arr[k] /= j;//连除        }
    }
}
复制代码
复制代码
//保存贝塞尔曲线单点结果
//接受的第一个参数为规律u,第二个参数为将要存放位置点的指针,第三个参数为所有控制点坐标数组,第四个参数为系数数组)
void computeBezPt(float u, point3D& bezPt,
    pointArray& ctrlPts, intArray& Cin) {    int n = ctrlPts.length - 1;    float bezFcn;//保存n次贝塞尔多项式的计算结果cin*u^i*(1-u)^(n-i)
    bezPt.x = bezPt.y = bezPt.z = 0;//初始化
    for (int k = 0; k <= n; k++) {//计算p(u)
        bezFcn = Cin.arr[k] * pow(u, k) * pow
        ((double)1-(double)u, (double)n-(double)k);
        bezPt.x += ctrlPts.arr[k].x * bezFcn;
        bezPt.y += ctrlPts.arr[k].y * bezFcn;
        bezPt.z += ctrlPts.arr[k].z * bezFcn;
    }

}
复制代码
复制代码
void bezier(pointArray& ctrlPts, int precision) {
    intArray Cin;
    Cin.length = ctrlPts.length;
    Cin.arr = new int[Cin.length];//根据控制点个数得到系数个数
    binomialCoefficient(Cin);//计算系数
    pointArray bezPts;//保存贝塞尔曲线的每个点
    bezPts.length = precision + 1;
    bezPts.arr = new point3D[bezPts.length];    float u;    for (int k = 0; k <= precision; k++) {
        u = float(k) / float(precision);
        computeBezPt(u, bezPts.arr[k], ctrlPts, Cin);//得出每个点的坐标    } 
         glBegin(GL_LINE_STRIP);        for (int i = 0; i < bezPts.length; i++) {            //连接点            glVertex3f(bezPts.arr[i].x, bezPts.arr[i].y, bezPts.arr[i].z);
        }
        glEnd();        delete[] bezPts.arr;        delete[] Cin.arr;
}
复制代码

 以下是用OpenGL的glut实现直线的绘制

复制代码
void renderScene(void) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glColor3f(0, 1, 0);
    glOrtho(-5, 5, -5, 5, -5, 5);
    bezier(ctrlPts_, 100);    //双缓存交换缓存以显示图像    glutSwapBuffers();    //每次更新显示    glutPostRedisplay();

}
复制代码
复制代码
int main(int argc, char** argv) {
    point3D ctrlPts[4] = { {1,2,3 },{2, 3, 4},{4, 5, 1},{0, 0, 0}};
    ctrlPts_.length = 4;
    ctrlPts_.arr = ctrlPts;
    glutInit(&argc, argv); //初始化glut
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);    //设置窗口的模式-深度缓存,单缓存,颜色模型
    glutInitWindowPosition(100, 100); //设置窗口的位置
    glutInitWindowSize(800, 800); //设置窗口的大小
    glutCreateWindow('3D Tech - GLUT Tutorial'); //创建窗口并赋予title
    glutDisplayFunc(renderScene);//调用renderScene把绘制传送到窗口
    glutMainLoop(); //进入事件循环等待
    return 0;
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多