本文使用 OpenGL 实现一个实时绘制 Bezier 曲线的小工具,并且动态实现其绘制过程。
🚀 代码: Github
鼠标控制
这次实验需要实现一个绘制 Bezier 曲线的小工具,因此第一步需要做的就是实现鼠标控制。
只需要使用glfwSetMouseButtonCallback
和glfwSetCursorPosCallback
设置鼠标点击回调事件和移动回调事件就可以获取到鼠标的点击事件和当前的位置。
1 | void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) { |
需要注意的是,获取到的鼠标位置是以左上角为原点建立的坐标系,我们还需要将其转换为标准坐标系或者使用正交投影使其映射到正确的位置。
绘制点
实现了鼠标控制之后,接下来就需要在屏幕上绘制用户点击的点,具体的方法之前实验已经做过很多次了,只需要使用glDrawArrays
并且指定绘制类型即可轻松地在屏幕上绘制点。
1 | // 画点 |
绘制 Bezier 曲线
Bezier 曲线可以用以下公式表示:
其中 $B_{i,n}$ 为伯恩斯坦(Bernstein)基函数,其多项式可以表达为:
根据这两条公式,我们可以开始编写程序。
首先,计算 Bernstein 基函数需要多次用到阶乘,这里将每次阶层的结果记录下来,避免多次计算浪费资源。因为int
类型最多可以存放 12 的阶乘,高于 12 的阶乘就会发生溢出。这里使用long long int
可以最多算到 21 的阶乘,最多可以画出 21 个控制点的曲线。
1 | // 计算阶乘 |
然后实现计算 Bernstein 基函数
1 | // 计算 bernstein 函数 |
最后将其画出来
1 | // 画线 |
然后我们将其辅助线绘制出来,查看其具体的绘制过程。具体的做法是递归地将每一条线找出每一个时刻的中间点,然后链接起来直到最后一个条线。
1 | // 辅助线 |
然后就可以得到以下的结果:
可以画更多的控制点查看效果:
这样,一个简单的 Bezier 曲线绘制工具就完成了。