bezier:该函数实现绘制 Bézier 曲线的功能。它使用一个控制点序列和一个 OpenCV::Mat 对象作为输入,没有返回值。它会使 t 在 0 到 1 的范围内进行迭代,并在每次迭代中使 t 增加一个微小值。对于每个需要计算的 t,将调用另一个函数 recursive_bezier,然后该函数将返回在 Bézier 曲线上 t 处的点。最后,将返回的点绘制在 OpenCV ::Mat 对象上。
recursive_bezier:该函数使用一个控制点序列和一个浮点数 t 作为输入, 实现 de Casteljau 算法来返回 Bézier 曲线上对应点的坐标。
完善以下代码
cv::Point2frecursive_bezier(const std::vector<cv::Point2f> &control_points,float t) { // TODO: Implement de Casteljau's algorithmreturn cv::Point2f();}voidbezier(const std::vector<cv::Point2f> &control_points, cv::Mat&window) { // TODO: Iterate through all t = 0 to t = 1 with small steps, and call de Casteljau's // recursive Bezier algorithm.}
cv::Point2frecursive_bezier(const std::vector<cv::Point2f> &control_points,float t) { // TODO: Implement de Casteljau's algorithm // if there's only one control point left, return itif(control_points.size() ==1)returncontrol_points[0]; std::vector<cv::Point2f> new_points; // Compute points for next recursive step, between every pair of control pointsfor(size_t i =0; i <control_points.size()-1; i++){float x = (1- t) *control_points[i].x + t *control_points[i+1].x;float y = (1- t) *control_points[i].y + t *control_points[i+1].y;new_points.push_back(cv::Point2f(x, y)); } // recursively continue on new set of pointsreturnrecursive_bezier(new_points, t);}
接下来,bezier函数就简单了,只需参考框架中给出的naive_bezier函数就行了。
voidbezier(const std::vector<cv::Point2f> &control_points, cv::Mat&window) { // TODO: Iterate through all t = 0 to t = 1 with small steps, and call de Casteljau's // recursive Bezier algorithm.constfloat step =0.001f;for(float t =0; t <=1; t += step) { cv::Point2f point =recursive_bezier(control_points, t);window.at<cv::Vec3b>(point) = cv::Vec3b(0,255,0); }}
voidaddColor(cv::Mat&img, cv::Point2f point, cv::Vec3b color) { cv::Point2f p1(point.x,point.y); cv::Point2f p2(point.x +1,point.y); cv::Point2f p3(point.x,point.y +1); cv::Point2f p4(point.x +1,point.y +1);float dx =point.x -p1.x;float dy =point.y -p1.y;img.at<cv::Vec3b>(p1) += color * ((1-dx) * (1-dy));img.at<cv::Vec3b>(p2) += color * (dx * (1-dy));img.at<cv::Vec3b>(p3) += color * ((1-dx) * dy);img.at<cv::Vec3b>(p4) += color * (dx * dy);}
最后将bezier重新打包一下:
voidbezier_sa(const std::vector<cv::Point2f> &control_points, cv::Mat&window){constdouble step =0.001f;for(double t =0; t <=1; t += step) { cv::Point2f point =recursive_bezier(control_points, t);addColor(window, point, cv::Vec3b(0,255,0)); }}