在此实现中如何引用控制点来绘制曲线?
How are control points referenced in this implementation for drawing a curve?
作为一项作业,我必须实现 De Casteljau 算法才能绘制贝塞尔曲线。我完全理解这个算法是如何工作的,以及它是如何产生曲线的,但我无法理解我所使用的算法的编码实现。
作业由三部分组成:
绘制一些控制点以及连接它们的边。
为范围 [0, 1] 中的给定参数 t
实施 De Casteljau 算法,这将根据此参数绘制所有 De Casteljau 线和贝塞尔点。这是在一个名为 drawDeCasteljau
的函数中完成的
通过从 t = 0.0
迭代到 t = 1.0
并将每个 t
传递到 drawDeCasteljau
并绘制每个贝塞尔点来绘制曲线。这是在一个名为 drawBezierCurve
的函数中完成的
程序将按以下方式运行:
- 单击以添加一个点和从最后一个点到这个新点的边
- 点击并按住一个点来拖动它
- 按
+
或-
增加或减少t
。 (这是我现在所在的位置)
- 按
1
显示t
当前值的De Casteljau线和贝塞尔点
- 按
2
绘制整条曲线
我们使用的示例算法是:
int numPoints = 3;
Point bezPoints[numPoints][numPoints];
void DrawBezier() {
for (float u = 0.0; u <= 1.0; u += 0.01) {
for (int diag = numPoints - 2; diasg >= 0; diag--) {
for (int i = 0; i <= diag; i++) {
int j = diag - i;
bezPoints[i][j] = (1.0 - u)*bezPoints[i][j + 1] + u*bezPoints[i + 1][j];
}
}
setPixel(bezPoints[0][0]);
}
}
我完全迷失了 bezPoints
矩阵,并且缺少对算法中任何控制点/线的引用。
在执行DrawBezier()
之前,bezPoints
应该已经填满了吗?
如果我有 3 个控制点,为什么 bezPoints
是一个 3x3 矩阵?它存储的这9个点到底是什么?
算法如何在不参考控制点/线的情况下工作?
编辑
感谢下方Nico的帮助,我成功绘制了贝塞尔曲线:
但是,我仍然在努力理解如何完成上面的第 2 步,以便绘制用于为 t
的当前值找到贝塞尔点的每条 De Casteljau 线。
控制点应该在矩阵的最远对角线上bezPoints
。你只需要习惯索引。它是这样工作的:如果你有 numPoints = 3
,控制点应该在对角线 2,即 bezPoints[0][2], bezPoints[1][1], bezPoints[2][0]
:
i \ j | 0 | 1 | 2
------+---+---+---
0 | C
1 | C
2 | C
diag
上的循环填充其他对角线,即应用算法一次迭代后的中间点:
i \ j | 0 | 1 | 2
------+---+---+---
0 |D=0 D=1 C
1 |D=1 C
2 | C
然后,终点在bezPoints[0][0]
。
变量u
表示曲线参数
作为一项作业,我必须实现 De Casteljau 算法才能绘制贝塞尔曲线。我完全理解这个算法是如何工作的,以及它是如何产生曲线的,但我无法理解我所使用的算法的编码实现。
作业由三部分组成:
绘制一些控制点以及连接它们的边。
为范围 [0, 1] 中的给定参数
t
实施 De Casteljau 算法,这将根据此参数绘制所有 De Casteljau 线和贝塞尔点。这是在一个名为drawDeCasteljau
的函数中完成的
通过从
t = 0.0
迭代到t = 1.0
并将每个t
传递到drawDeCasteljau
并绘制每个贝塞尔点来绘制曲线。这是在一个名为drawBezierCurve
的函数中完成的
程序将按以下方式运行:
- 单击以添加一个点和从最后一个点到这个新点的边
- 点击并按住一个点来拖动它
- 按
+
或-
增加或减少t
。 (这是我现在所在的位置) - 按
1
显示t
当前值的De Casteljau线和贝塞尔点
- 按
2
绘制整条曲线
我们使用的示例算法是:
int numPoints = 3;
Point bezPoints[numPoints][numPoints];
void DrawBezier() {
for (float u = 0.0; u <= 1.0; u += 0.01) {
for (int diag = numPoints - 2; diasg >= 0; diag--) {
for (int i = 0; i <= diag; i++) {
int j = diag - i;
bezPoints[i][j] = (1.0 - u)*bezPoints[i][j + 1] + u*bezPoints[i + 1][j];
}
}
setPixel(bezPoints[0][0]);
}
}
我完全迷失了 bezPoints
矩阵,并且缺少对算法中任何控制点/线的引用。
在执行DrawBezier()
之前,bezPoints
应该已经填满了吗?
如果我有 3 个控制点,为什么 bezPoints
是一个 3x3 矩阵?它存储的这9个点到底是什么?
算法如何在不参考控制点/线的情况下工作?
编辑
感谢下方Nico的帮助,我成功绘制了贝塞尔曲线:
但是,我仍然在努力理解如何完成上面的第 2 步,以便绘制用于为 t
的当前值找到贝塞尔点的每条 De Casteljau 线。
控制点应该在矩阵的最远对角线上bezPoints
。你只需要习惯索引。它是这样工作的:如果你有 numPoints = 3
,控制点应该在对角线 2,即 bezPoints[0][2], bezPoints[1][1], bezPoints[2][0]
:
i \ j | 0 | 1 | 2
------+---+---+---
0 | C
1 | C
2 | C
diag
上的循环填充其他对角线,即应用算法一次迭代后的中间点:
i \ j | 0 | 1 | 2
------+---+---+---
0 |D=0 D=1 C
1 |D=1 C
2 | C
然后,终点在bezPoints[0][0]
。
变量u
表示曲线参数