作业三

作业

贝塞尔曲线

贝塞尔曲线是通过控制点来绘制的曲线
其完全由其控制点决定其形状 n个控制点对应着n-1阶的贝塞尔曲线
t[0.0..1.0]作为参数来细分曲线

很明显我们可以通过递归来计算它

代码

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> points;
    for (size_t i = 0; i + 1 < control_points.size(); i++) {
        auto cur_point = control_points[i];
        auto next_point = control_points[i + 1];
        auto diff_point = next_point - cur_point;

        // auto iterate_point = cur_point * t + next_point * (1 - t); 
        auto iterate_point = cur_point + diff_point * t;
        points.emplace_back(iterate_point);
    }


    return recursive_bezier(points, t);

}

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) {
    auto res_point = recursive_bezier(control_points, t);
    window.at<cv::Vec3b>(res_point)[1] = 255;
  }

}

也可以通过多项式公式计算 公式如下图

代码

void naive_bezier(const std::vector<cv::Point2f> &points, cv::Mat &window)
{
    auto &p_0 = points[0];
    auto &p_1 = points[1];
    auto &p_2 = points[2];
    auto &p_3 = points[3];

    for (double t = 0.0; t <= 1.0; t += 0.001) 
    {
        auto point = std::pow(1 - t, 3) * p_0 + 3 * t * std::pow(1 - t, 2) * p_1 +
                 3 * std::pow(t, 2) * (1 - t) * p_2 + std::pow(t, 3) * p_3;

        window.at<cv::Vec3b>(point.y, point.x)[2] = 255;
    }
}

引用

最后修改:2023 年 02 月 05 日
如果觉得我的文章对你有用,请随意赞赏