作业要求:
需要实现 de Casteljau 算法来绘制由 4 个控制点表示的 Bézier 曲线。
De Casteljau 算法说明如下:
1. 考虑一个 p 0 , p 1 , ... p n 为控制点序列的 Bézier 曲线。首先,将相邻的点连接起来以形成线段。
2. 用 t : (1 − t) 的比例细分每个线段,并找到该分割点。
3. 得到的分割点作为新的控制点序列,新序列的长度会减少一。
4. 如果序列只包含一个点,则返回该点并终止。否则,使用新的控制点序列并转到步骤 1。
使用 [0,1] 中的多个不同的 t 来执行上述算法,你就能得到相应的 Bézier 曲线。
第一步:
实现 de Casteljau 算法来返回 Bézier 曲线上对应点的坐标。
第二步:
实现绘制 Bézier 曲线的功能。
cv::Point2f recursive_bezier(const std::vector<cv::Point2f> &control_points, float t)
{
if(control_points.size() == 2 )//只剩两点时为递归结束条件
return t * control_points[1] + (1 - t) * control_points[0];
std::vector<cv::Point2f> temp_control_points;
for (int i=0; i<control_points.size() - 1; i++)
temp_control_points.push_back((1 - t) * control_points[i] + t * control_points[i+1]);
return recursive_bezier(temp_control_points, t);//递归
}
void bezier(const std::vector<cv::Point2f> &control_points, cv::Mat &window)
{
float t = 0.0;
while(t <= 1.0)
{
auto point = recursive_bezier(control_points, t);//得到t情况下的一个点
window.at<cv::Vec3b>(point.y, point.x)[1]= 255; //绘制贝塞尔*绿色*曲线
t += 0.001;
}
}