这里回顾GAMES101 HW4,这次作业的内容是贝塞尔曲线。

课程主页:

课程作业:

课程视频:

recursive_bezier

recursive_bezier使用讲义中介绍的递归算法实现即可:

cv::Point2f recursive_bezier(const std::vector<cv::Point2f> &control_points, float t) 
{
    // TODO: Implement de Casteljau's algorithm
    int n = control_points.size();
    if (n == 1) {
        return control_points[0];
    }
    std::vector<cv::Point2f> res;
    for (int i = 0; i < n - 1; i++) {
        auto point = t * control_points[i] + (1 - t) * control_points[i + 1];
        res.push_back(point);
    }

    return recursive_bezier(res, t);
}

bezier

枚举得到贝塞尔曲线上的点,根据这个点和像素点的距离进行上色(反走样):

void bezier(const std::vector<cv::Point2f> &control_points, cv::Mat &window, bool flag) 
{
    // 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) {
        auto point = recursive_bezier(control_points, t);
        int x = point.x;
        int y = point.y;
        if (flag) {
            // 反走样
            int y_min = int(point.y);
            int y_max = y_min + 1;
            int x_min = int(point.x);
            int x_max = x_min + 1;
            // 找到最近的位置
            if (point.y < y_min + 0.5) {
                y = y_min;
            } else {
                y = y_max;
            }
            if (point.x < x_min + 0.5) {
                x = x_min;
            } else {
                x = x_max;
            }
        }
        // 该函数使用的参数为int
        window.at<cv::Vec3b>(y, x)[1] = 255;
    }
}

示例

参考代码的结果:

反走样后的结果: