实验报告四bezier曲线
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四Bezier曲线的绘制
1. 实验目的
练习Bezier曲线的绘制和de Casteljau算法。
2. 实验内容和要求
按要求完成如下一个作业,提交纸质实验报告,同时提交实验报告和代码的电子版。
实现Bezier曲线的de Casteljau递推算法,能够对任意介于0和1之间的参数t计算Bezier曲线上的点,然后依次连接这些点生成Bezier曲线。要求:
对[0,1]参数区间进行100等分。
控制点的数目至少为5个,即Bezier曲线的次数不低于4次。
de Casteljau算法用一个函数单独实现。
绘制Bezier曲线的同时还要绘制其控制多边形。
至少绘制两条Bezier曲线,具有不同的次数,颜色和曲线宽度。
3.算法描述
Bezier Curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。
曲线定义:起始点、终止点、控制点。
通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bezier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。
以下公式中:B(t)为t时间下点的坐标;P0为起点,Pn为终点,Pi为控制点。
一阶贝塞尔曲线如下,意义由 P0 至 P1 的连续点,描述的是一条线段:
二阶贝塞尔曲线(抛物线:P1-P0为曲线在P0处的切线):
原理:由 P0 至 P1 的连续点 Q0,描述一条线段。
由 P1 至 P2 的连续点 Q1,描述一条线段。
由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。
4. 源程序代码
#include
#include
#include
GLsizei winWidth = 600, winHeight = 600;
GLfloat xwcMin = -150.0, xwcMax = 150.0;
GLfloat ywcMin = -300.0, ywcMax = 300.0;
class wcPt3D{
public:
GLfloat x, y, z; };
void init(){
glClearColor(1.0, 1.0, 1.0, 1.0); }
void plotPoint(wcPt3D bezCurevePt){
glBegin(GL_POINTS);
glVertex2f(bezCurevePt.x, bezCurevePt.y);
glEnd(); }
void binomiaCoeffs(GLint n, GLint * C){
GLint k, j;
for (k = 0; k <= n; k++)
C[k] = 1;
for (j = n; j >= k + 1; j--)
C[k] *= j;
for (j = n - k; j >= 2; j--)
C[k] /= j; }
void computeBezPt(GLfloat u, wcPt3D * bezPt, GLint nCtrlPts, wcPt3D *CtrlPts, GLint *C){ GLint k, n = nCtrlPts - 1;
GLfloat bezBlendFcn;
bezPt->x = bezPt->y = bezPt->z = 0.0;
for (k = 0; k bezBlendFcn = C[k] * pow(u, k) * pow(1 - u, n - k); bezPt->x += CtrlPts[k].x * bezBlendFcn; bezPt->y += CtrlPts[k].y * bezBlendFcn; bezPt->z += CtrlPts[k].z * bezBlendFcn; } } void bezier(wcPt3D * ctrlPts, GLint nCtrlPts, GLint nBezCurvePts){ wcPt3D bezCurvePt; GLfloat u; GLint *C, k; C = new GLint[nCtrlPts]; binomiaCoeffs(nCtrlPts - 1, C); for (k = 0; k <= nBezCurvePts; k++){ u = GLfloat(k) / GLfloat(nBezCurvePts); computeBezPt(u, &bezCurvePt, nCtrlPts, ctrlPts, C); plotPoint(bezCurvePt); } delete[]C; } void displayFcn(void){ GLint nCtrlPts = 5, nCtrlPts2 = 6, nBezCurvePts = 1000; wcPt3D ctrlPts[5] = { { -135.0, -59.0, 0.0 }, { -59.0, 95.0, 0.0 }, { 0.0, -40.0, 0.0 }, { 70.0, 120.0, 0.0 }, { 78, -125.0, 0.0 } }; wcPt3D ctrlPts2[6] = { { -118.0, 20.0, 0.0 }, { -85.0, 45.0, 0.0 }, { -26.0, -126.0, 0.0 }, { 38.0, 88.0, 0.0 }, { 58.0, 188.0, 0.0 }, { 108.0, 98.0, 0.0 } }; glClear(GL_COLOR_BUFFER_BIT); glPointSize(6); glColor3f(0.0, 1.0, 1.0); bezier(ctrlPts, nCtrlPts, nBezCurvePts); glPointSize(5); glColor3f(1.0, 0.0, 1.0); bezier(ctrlPts2, nCtrlPts2, nBezCurvePts); glColor3f(0.0, 0.0, 1.0); glBegin(GL_LINES); glVertex2f(-135.0, -59.0); glVertex2f(-59.0, 95.0); glVertex2f(-59.0, 95.0); glVertex2f(0.0, -40.0); glVertex2f(0.0, -40.0); glVertex2f(70.0, 120.0); glVertex2f(70.0, 120.0); glVertex2f(78.0, -125.0); glVertex2f(-118.0, 20.0); glVertex2f(-85.0, 45.0); glVertex2f(-85.0, 45.0); glVertex2f(-26.0, -126.0); glVertex2f(-26.0, -126.0); glVertex2f(38.0, 88.0); glVertex2f(38.0, 88.0); glVertex2f(58.0, 188.0); glVertex2f(58.0, 188.0); glVertex2f(108.0, 98.0); glEnd(); glFlush(); }