NURBS曲线绘制

        工作需要,最近做非均匀B样条曲线数据库建立。为养成良好的工作学习习惯,特此作总结,并希望以后在计算机仿真学上能有更深的造诣,以激励自己不断进步。

         续前,前段时间终于把NURBS调通,甚是高兴!

        NURBS样条曲线,这期间经过几次曲折。

       第一次是参考网上的资料做出了均匀B样条曲线,后来拿到客户那里去,发现大致形状一致,但坐标对应差的太远,调整系数还是不对。没办法,我得继续查找新的方法。改进之。

       第二次重大突破是在施法中那本书里找到一个绘NURBS的例子,根据多边形逼近原理,逐步逼近的方式代数形式求出NURBS图形,这次比上次更为接近AtuoCAD中的图形。但后拿到客户验证的时候,发现在图形极小的时候,出现锯齿状,不圆滑。这不符合工艺要求。yeah!go on。。。

      Oh, My god!我不怕挑战,我不怕找不到答案。我相信发现问题,就等于问题解决了一半。既然问题解决了一半,我还担心剩下的工作不能完成。Yes,我继续了,把施法中的那本书和其他相关论文重新认真读了遍,在众多文章中,我尝试去用一种的新方法去做,多次调整后,发现新方法接近了答案,hehe,在疲惫和意志力的考验下,我又一次度过了难关,问题很快解决了。这次是全新的NURBS,也很光滑。但不是所有点都完全吻合,这是让我担心的,老总说客户那边吹的急,还没完全吻合,那先用这个应付下吧....

      第三次,一天早上老总说“陈啊,能不能快点,现在发货压力大,先做个基本符合要求的”。我说“总啊,我周末都没休息,我一直在找方案,我尽快吧!" 事情往往没想到,我一直怀疑的地方不是,成功往往在拐角处,我偷偷去调换了另一个参数,当然参考了别人的文章,因为之前一直坚信施法中那本书,所以也没产生怀疑。哇塞,奇迹就以这样不经意的方式出现了,我做到了,完全吻合了,随便怎么变!

     第二天我再完善了部分功能,发了份给老总,老总后来回信息“陈啊,很好,很强大!”。“总啊,嘿嘿,不是小Kiss嘛。”

      Anyway, 不要放弃,咬咬牙做成功,发现问题就等于问题解决了一半。中间的过程肯定不好受,为了中途那一刻轻松,march on!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
下面是一个绘制二次Bezier曲线的示例代码: ```c++ void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPointSize(5.0); glColor3f(0.0, 1.0, 0.0); glBegin(GL_POINTS); for (int i = 0; i < 3; i++) { glVertex2f(control_points[i].x, control_points[i].y); } glEnd(); glColor3f(1.0, 0.0, 0.0); glBegin(GL_LINE_STRIP); for (float t = 0.0; t <= 1.0; t += 0.01) { float x = (1 - t) * (1 - t) * control_points[0].x + 2 * t * (1 - t) * control_points[1].x + t * t * control_points[2].x; float y = (1 - t) * (1 - t) * control_points[0].y + 2 * t * (1 - t) * control_points[1].y + t * t * control_points[2].y; glVertex2f(x, y); } glEnd(); glFlush(); } ``` 这个函数假定了有三个控制点,存储在一个名为control_points的数组中。在这个函数中,首先使用glBegin和glEnd绘制了控制点。然后,使用glBegin和glEnd绘制了Bezier曲线。在for循环中,我们计算出曲线上的点,然后使用glVertex2f将它们添加到GL_LINE_STRIP中。 下面是一个绘制B样条曲线的示例代码: ```c++ void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPointSize(5.0); glColor3f(0.0, 1.0, 0.0); glBegin(GL_POINTS); for (int i = 0; i <= degree; i++) { glVertex2f(control_points[i].x, control_points[i].y); } glEnd(); glColor3f(1.0, 0.0, 0.0); glBegin(GL_LINE_STRIP); for (float u = 0.0; u <= 1.0; u += 0.01) { float x = 0.0; float y = 0.0; for (int i = 0; i <= degree; i++) { float basis = basis_function(i, degree, u); x += control_points[i].x * basis; y += control_points[i].y * basis; } glVertex2f(x, y); } glEnd(); glFlush(); } ``` 在这个函数中,我们假定了一个名为degree的B样条曲线度数,并且使用一个名为control_points的数组存储控制点。在for循环中,我们计算出曲线上的点,然后使用glVertex2f将它们添加到GL_LINE_STRIP中。为了计算B样条曲线上的点,我们需要使用一个B样条基函数,basis_function。下面是这个基函数的代码: ```c++ float basis_function(int i, int j, float u) { if (j == 0) { if (u >= knot_vector[i] && u < knot_vector[i + 1]) { return 1.0; } else { return 0.0; } } else { float first_term = 0.0; float second_term = 0.0; if (knot_vector[i + j] != knot_vector[i]) { first_term = (u - knot_vector[i]) / (knot_vector[i + j] - knot_vector[i]) * basis_function(i, j - 1, u); } if (knot_vector[i + j + 1] != knot_vector[i + 1]) { second_term = (knot_vector[i + j + 1] - u) / (knot_vector[i + j + 1] - knot_vector[i + 1]) * basis_function(i + 1, j - 1, u); } return first_term + second_term; } } ``` 在这个函数中,我们使用递归来计算B样条基函数。对于每个i和j,我们都需要计算基函数的值。如果j为0,则我们检查u是否在knot_vector[i]和knot_vector[i+1]之间。如果是,则基函数的值为1.0,否则为0.0。如果j大于0,则我们使用递归计算基函数的值。我们计算两个术语,第一个术语和第二个术语。对于第一个术语,我们计算出一个比率,然后将其乘以基函数i,j-1在u处的值。对于第二个术语,我们计算出另一个比率,然后将其乘以基函数i+1,j-1在u处的值。最后,我们将两个术语相加并返回结果。 下面是一个绘制NURBS曲线的示例代码: ```c++ void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPointSize(5.0); glColor3f(0.0, 1.0, 0.0); glBegin(GL_POINTS); for (int i = 0; i <= degree; i++) { glVertex2f(control_points[i].x, control_points[i].y); } glEnd(); glColor3f(1.0, 0.0, 0.0); glBegin(GL_LINE_STRIP); float u = 0.0; for (int i = 0; i <= num_segments; i++) { float x = 0.0; float y = 0.0; for (int j = 0; j <= degree; j++) { float basis = basis_function(j, degree, u); x += control_points[j].x * weights[j] * basis; y += control_points[j].y * weights[j] * basis; } glVertex2f(x, y); u += step_size; } glEnd(); glFlush(); } ``` 在这个函数中,我们假定了一个名为degree的NURBS曲线度数,并且使用一个名为control_points的数组存储控制点,以及一个名为weights的数组存储控制点的权重。我们还需要指定一个名为num_segments的变量,它表示我们要将曲线分成多少个线段。在for循环中,我们计算出曲线上的点,然后使用glVertex2f将它们添加到GL_LINE_STRIP中。为了计算NURBS曲线上的点,我们需要使用B样条基函数和权重。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值