根据Bezier曲线的定义公式实现Bezier曲线的绘制

article/2025/11/9 18:10:10

Bezier曲线的定义公式

在这里插入图片描述
Pi是曲线上点的坐标(x,y,(z=0)), Bi,n(t)伯恩斯坦公式,绘制Bezier曲线的第一种方法是根据这个公式来绘制。首先看看绘制的效果:
在这里插入图片描述

(1)计算定义中多项式的值

在这里插入图片描述
首先要求伯恩斯坦公式的多项式的值Cni,写成后面这种阶乘的形式方便用程序去表达了:

//计算定义中多项式的值
void GetCnk(GLint n,GLint *c)//n是控制点的个数,C用来存多项式值的数组
{GLint i,j;for(j=0;j<n;j++){//循环前先从n!中把i!消掉,注意体会c[j]=1;for(i=n-1;i>=j+1;i--)c[j]=c[j]*i;for(i=n-1-j;i>=2;i--)c[j]=c[j]/i;}
}

(2)计算曲线上点的坐标

在这里插入图片描述
Pi是曲线上点的坐标(x,y,(z=0)),所以我们可以把p(t)表示成三个坐标分量的形式:
在这里插入图片描述
在这里插入图片描述

//计算曲线上点的坐标
void GetPointPr(GLint *c,GLfloat t,Pt3D *Pt,GLint ControlN,Pt3D *ControlP)
{//c是存多项式值的数组,t是参数值,Pt是曲线上某点坐标,ControlN是控制点个数,ControlP是控制点坐标GLint i,n=ControlN;GLfloat Berstein;Pt->x=0.0;Pt->y=0.0;Pt->z=0.0;for(i=0;i<ControlN;i++){Berstein=c[i]*pow(t,i)*pow(1-t,n-1-i);Pt->x+=ControlP[i].x*Berstein;Pt->y+=ControlP[i].y*Berstein;Pt->z+=ControlP[i].z*Berstein;}
}

(3)根据求出的坐标绘制Bezier曲线

void Bezierdraw(GLint m,GLint ControlN,Pt3D *ControlP)
{//m是曲线上点的个数,ControlN是控制点个数,ControlP是控制点坐标GLint *C,i;Pt3D CurvePt;//保存当前点坐标C=new GLint[ControlN];//存多项式系数的数组CGetCnk(ControlN,C);glColor3f(1.0,0.0,0.0);glPointSize(3);//曲线画粗点和控制图形区分glBegin(GL_POINTS);for(i=0;i<=m;i++){GetPointPr(C,(GLfloat)i/m,&CurvePt,ControlN,ControlP);glVertex2f(CurvePt.x,CurvePt.y);}glEnd();delete [] C;
}

总的代码:

#include <GL/freeglut.h>
#include <math.h>
class Pt3D{public:GLfloat x,y,z;
};//坐标类//计算定义中多项式的值
void GetCnk(GLint n,GLint *c)//n是控制点的个数,C用来存多项式值的数组
{GLint i,j;for(j=0;j<n;j++){//循环前先从n!中把i!消掉,注意体会c[j]=1;for(i=n-1;i>=j+1;i--)c[j]=c[j]*i;for(i=n-1-j;i>=2;i--)c[j]=c[j]/i;}
}//计算曲线上点的坐标
void GetPointPr(GLint *c,GLfloat t,Pt3D *Pt,GLint ControlN,Pt3D *ControlP)
{//c是存多项式值的数组,t是参数值,Pt是曲线上某点坐标,ControlN是控制点个数,ControlP是控制点坐标GLint i,n=ControlN;GLfloat Berstein;Pt->x=0.0;Pt->y=0.0;Pt->z=0.0;for(i=0;i<ControlN;i++){Berstein=c[i]*pow(t,i)*pow(1-t,n-1-i);Pt->x+=ControlP[i].x*Berstein;Pt->y+=ControlP[i].y*Berstein;Pt->z+=ControlP[i].z*Berstein;}
}//根据控制点,画曲线上的500个点
void Bezierdraw(GLint m,GLint ControlN,Pt3D *ControlP)
{//m是曲线上点的个数,ControlN是控制点个数,ControlP是控制点坐标GLint *C,i;Pt3D CurvePt;//保存当前点坐标C=new GLint[ControlN];//存多项式系数的数组CGetCnk(ControlN,C);glColor3f(1.0,0.0,0.0);glPointSize(3);//曲线画粗点和控制图形区分glBegin(GL_POINTS);for(i=0;i<=m;i++){GetPointPr(C,(GLfloat)i/m,&CurvePt,ControlN,ControlP);glVertex2f(CurvePt.x,CurvePt.y);}glEnd();delete [] C;
}
void myinit(void)
{glClearColor(1.0f,1.0f,1.0f,1.0f);
}
//窗口大小变化时的回调函数
void myReshape(GLsizei w, GLsizei h)
{//设定视区glViewport(0, 0, w, h);//设定透视方式glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(-100.0,100.0,-100.0,100.0);
}
void display(void)
{//设置清除屏幕的颜色,并清除屏幕glClear(GL_COLOR_BUFFER_BIT);GLint ControlN=4;//4个控制点GLint m=500;//曲线由500个点绘制而成Pt3D ControlP[4]={{-80.0,-40.0,0.0},{-10.0,90.0,0.0},{10.0,-90.0,0.0},{80.0,40.0,0.0}};//控制点坐标//画曲线Bezierdraw(m,ControlN,ControlP);//画控制图形glColor3f(0.0,0.0,0.0);glBegin(GL_LINE_STRIP);for(int i=0;i<ControlN;i++){glVertex3f(ControlP[i].x,ControlP[i].y,ControlP[i].z);}glEnd();//交换前后缓冲区glutSwapBuffers();
}
int main(int argc, char* argv[])
{glutInit(&argc, argv);//根据定义//初始化OPENGL显示方式glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);//设定OPENGL窗口位置和大小glutInitWindowSize (400, 400); glutInitWindowPosition (100, 100);//打开窗口glutCreateWindow ("根据定义");//调用初始化函数myinit();//设定窗口大小变化的回调函数glutReshapeFunc(myReshape);//开始OPENGL的循环glutDisplayFunc(display); glutMainLoop();return 0;
}

不过这样做计算量很大,要用公式把所有曲线上的点都绘制出来,不适于工程,更加简单、快捷、效率高的是de Castel jau的递推算法实现Bezier曲线的绘制,我写在了另一篇文章中https://blog.csdn.net/derbi123123/article/details/105317678


http://chatgpt.dhexx.cn/article/JCcvOPI6.shtml

相关文章

Bezier曲线描述

Bezier曲线 1.Bezier曲线的定义 当用曲线段拟合曲线f(x)时&#xff0c;可以把曲线表示为许多小线段φi(x)之和&#xff0c;其中φi(x)称为基&#xff08;混合&#xff09;函数。 这些基&#xff08;混合&#xff09;函数是要用于计算和显示的。因此&#xff0c;经常选择多项式…

Bezier曲线的绘制

Bezier曲线是参数多项式曲线,它由一组控制多边形折线(控制多边形)的顶点唯一定义,在控制多边形的各顶点中,只有第一个和最后一个顶点在曲线上,其他的顶点则用以定义曲线的导数,阶次和形状 Bezier曲线的数学基础是能够在第一个和最后一个顶点之间进行插值的一个多项式混合函数,…

Bezier曲线的生成算法

Bezier曲线的生成方法 生成一条Bezier曲线实际上就是要求出曲线上的点。 1.根据定义直接生成Bezier曲线 定义&#xff1a; 其中 那么生成步骤为&#xff1a; ①首先给出 的递归计算式&#xff1a; ②&#xff1a;将表示成分量形式 由于的计算量大&#xff0c;算法效率不高…

bezier曲线解析与代码(c++)

前言&#xff1a; 作为rhino重度用户&#xff0c;我对于nurbs建模早有耳闻&#xff0c;但对于何为nurbs却不得其解。最近借上《计算机辅助设计》课程的机会&#xff0c;对此作了一些深入的学习&#xff0c;于是在此记录一下一些课程笔记和课后思考。了解nurbs&#xff0c;主要对…

Bezier曲线构造

Bezier曲线构造 曲线公式 曲 线 &#xff1a; C ( u ) ∑ i 0 n B n , i ( u ) P i 基 函 数 &#xff1a; B n , i n ! i ! ( n − i ) ! u i ( 1 − u ) n − i 曲线&#xff1a;C(u) \sum^n_{i0}B_{n,i}(u)P_i\\ 基函数&#xff1a;B_{n,i}\frac{n!}{i!(n-i)!}u^i(1-u)…

java版 贝塞尔曲线算法

public void test() {CvPoint controlPoint[] new CvPoint[4];controlPoint[0] new CvPoint(50, 60); //起点controlPoint[1] new CvPoint(130, 200); //控制点controlPoint[2] new CvPoint(300, 360); //控制点controlPoint[3] new CvPoint(400, 600); //终点int n cont…

Bezier曲线原理及实现代码(c++)

http://devres.zoomquiet.io/data/20110728232822/index.html Bezier曲线原理及实现代码&#xff08;c&#xff09; 一、原理&#xff1a; 贝塞尔曲线于1962年&#xff0c;由法国工程师皮埃尔贝塞尔&#xff08;Pierre Bzier&#xff09;所广泛发表&#xff0c;他运用贝塞尔曲线…

用Java实现可交互的贝塞尔曲线(Bezier curve)

关于贝塞尔曲线的详细数学原理及公式可参考&#xff1a; 贝塞尔曲线_百度百科 我们来谈谈贝塞尔曲线 本文给出了一种用Java实现贝塞尔曲线的方法&#xff0c;并且可以用鼠标拖动改变锚点。 效果演示图&#xff1a; 这里引用百度百科给出的公式&#xff1a; 二次方公式 三次方…

Bezier曲线简介

Bezier曲线简介 Bezier曲线&#xff0c;又有人叫贝赛尔曲线&#xff0c;贝兹曲线&#xff0c;在计算机绘图中经常被用到&#xff0c;由于前些天事件要用到这个&#xff0c;所以就研究了下。 有了参考资料&#xff0c;其实也不是很复杂。 曲线的介绍&#xff08;转自维基百科,见…

Bezier曲线原理及其代码实现

Bezier曲线原理及实现代码&#xff08;c&#xff09; 一、原理&#xff1a; 贝塞尔曲线于1962年&#xff0c;由法国工程师皮埃尔?贝塞尔&#xff08;Pierre B?zier&#xff09;所广泛发表&#xff0c;他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由 Paul de Cast…

Bezier曲线及其性质

本文为Bezier曲线mooc教程学习笔记。 目录 Bezier曲线与曲面[1] Bezier曲线的背景[2] Bezier曲线[3] Bezier曲线详细定义[4] Bezier曲线举例[5] Bernstein 基函数性质[6] 贝塞尔曲线的性质[7] Bezier曲线的生成[8] Bezier曲线的拼接[9] Bezier曲线的升阶与降阶 Bezier曲线与曲面…

Bezier曲线原理

一、原理&#xff1a; 贝塞尔曲线于1962年&#xff0c;由法国工程师皮埃尔贝塞尔&#xff08;Pierre Bzier&#xff09;所广泛发表&#xff0c;他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau 于1959年运用de Casteljau 算法开发&#xff0c;以稳…

如何将多张图片合成一个pdf?

如何将多张图片合成一个pdf&#xff1f;平时我们都喜欢将word或者ppt文件转换成pdf后再使用&#xff0c;除此之外&#xff0c;我们还会将多张图片合并转换成pdf文件&#xff0c;大家会用什么方法将图片合并成pdf呢&#xff1f;我相信有很多小伙伴会使用这个方法&#xff0c;先将…

怎么把四个图片合成一个图片?

怎么把四个图片合成一个图片&#xff1f;关于图片的合成&#xff0c;我们一般都会用到图片处理软件来进行。但是对于一些职场新人来说&#xff0c;他根本不会用一些专业的图片处理软件&#xff0c;那么这个问题对他来说就是非常棘手的。其实遇到这样的问题&#xff0c;新人朋友…

python将多张图片合并成一张图片

文章目录 说明&#xff1a;合并图片的三个过程1、参考原博主的&#xff1a;2、优化第一个数量问题&#xff1a;3、优化俩个问题&#xff08;数量不限性状按比例变小&#xff09;4、优化黑行高度问题5、合成图片不清晰问题&#xff1a;总结下&#xff1a; 说明&#xff1a; 今天…

如何把一张图片分割成几张

把一张图片分割成几张的方法&#xff1a; 工具/原料&#xff1a;硬件&#xff1a;电脑、软件&#xff1a;Photoshop 7.0、系统&#xff1a;Windows10专业版64位操作系统。 1、打开平PS&#xff0c;进入新建文档里面&#xff0c;然后把图片直接拉到界面中。或者直接打开图片。 2…

jpg怎么合成一份_如何将多张图片合成一个文件

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 将多张图片合成一个文件的方法是&#xff1a; 1、将所有图片拖到一个文件夹里&#xff0c;鼠标右键点击“添加压缩”。 2、点击确定&#xff0c;这样就成了一个文件。 计算机(compu…

怎样能把两张照片拼成一张图片,5种工具分享

怎样能把两张照片拼成一张图片&#xff1f;图片拼合的应用场景是很多的。比如将几张相册中的照片拼成一张合影、将多个地图截图拼合在一起形成一个更大的区域地图、将多个漫画图像合并成一本漫画册等。这项技术可以方便地将多张图片整合为一张&#xff0c;节省时间和精力。 因此…

怎么将几张照片合成一张图片,简单步骤易学

怎么将几张照片合成一张图片&#xff1f;在当代社会&#xff0c;图片已经成为了人们生活和工作中不可或缺的重要元素。无论是在网上浏览、社交媒体、电商平台、还是在企业营销、科研教育、娱乐创作等各种场合中&#xff0c;都有着广泛的应用。而将不同的图片进行合并&#xff0…

多张图片怎么合成一个pdf?

多张图片怎么合成一个pdf&#xff1f;相信大家和我一样&#xff0c;每天的工作或者生活学习都离不开pdf文件&#xff0c;因为pdf文件拥有更好的稳定性和安全性&#xff0c;不管是在电脑还是在其他设备上&#xff0c;都能正常的打开&#xff0c;而且pdf文件不易编辑的特性&#…