实现de Casteljau算法来绘制由4个控制点表示的Bézier曲线。需要修改main.cpp中的如下函数:
De Casteljau 算法说明如下:
使用[0,1] 中的多个不同的t来执行上述算法
例子如下
//cv::Mat &window:表示屏幕矩阵;矩阵内元素为CV_8UC3类型(无符号8位整数,RGB三通道,cv::Vec3b)
void bezier(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.
for(double t = 0.0; t < 1.0; t += 0.001){
cv::Point2f point = recursive_bezier(control_points, t);
// 绘制坐标(point.y, point.x)的颜色为绿色,[1]表示RGB中的G
window.at<cv::Vec3b>(point.y, point.x)[1] = 255;
}
}
//cv::Point2f float类型的二维点坐标
cv::Point2f recursive_bezier(const std::vector<cv::Point2f> &control_points, float t)
{
// TODO: Implement de Casteljau's algorithm
if(control_points.size() == 1) return control_points[0];
std::vector<cv::Point2f> next_layer_control_points;
for(int i = 0; i < control_points.size() - 1; i++){
cv::Point2f p0 = control_points[i];
cv::Point2f p1 = control_points[i+1];
cv::Point2f p2 = p0 + t * (p1 - p0);
next_layer_control_points.push_back(p2);
}
return recursive_bezier(next_layer_control_points, t);
}
对于一个曲线上的点,不只把它对应于一个像
素,需要根据到像素中心的距离来考虑与它相邻的像素的颜色
double get_dist(cv::Point2f point1, cv::Point2f point2){//计算两点的哈夫曼距离
return fabs(point1.x - point2.x) + fabs(point1.y - point2.y);
}
//cv::Mat &window:表示屏幕矩阵;矩阵内元素为CV_8UC3类型(无符号8位整数,RGB三通道,cv::Vec3b)
void bezier(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.
for(double t = 0.0; t < 1.0; t += 0.001){
cv::Point2f point = recursive_bezier(control_points, t);
cv::Point2f point0( std::min(floor(point.x), ceil(point.x)), std::min(floor(point.y), ceil(point.y)) );
double dist;
std::vector<double> bias{0.5, -0.5};
for(int i = 0; i < 4; i++){
cv::Point2f centerPoint(point0.x + bias[i % 2], point0.y + bias[i % 2]);//计算中心点
dist = get_dist(point, centerPoint);
window.at<cv::Vec3b>(centerPoint.y, centerPoint.x)[1] = 255 * (3 - dist) / 3;
}
}
}
如往常一样
$ mkdir build
$ cd build
$ cmake ..
$ make
$ ./BezierCurve
通过点击屏幕来设置控制点