GAMES101——作业4 Bézier 曲线(含提高:反走样)

任务

        bezier:该函数实现绘制 Bézier 曲线的功能。它使用一个控制点序列和一个OpenCV:: Mat 对象作为输入,没有返回值。它会使 t 0 1 的范围内进行迭代,并在每次迭代中使 t 增加一个微小值。对于每个需要计算的 t ,将调用另一个函数 recursive_bezier ,然后该函数将返回在 Bézier 曲线上 t处的点。最后,将返回的点绘制在 OpenCV :: Mat 对象上。
        recursive_bezier:该函数使用一个控制点序列和一个浮点数 t 作为输入,实现 de Casteljau 算法来返回 Bézier 曲线上对应点的坐标。

实现

        本次的任务相比上一次简单。代码量很少且原理简单,这里直接给出代码。

        recursive_bezier
cv::Point2f recursive_bezier(const std::vector<cv::Point2f> &control_points, float t) 
{
    auto points = control_points;   //获取控制点序列
    //当控制点序列点不为1时,每次都遍历一次序列,获取新的点序列
    while(points.size() >1){
        std::vector<cv::Point2f> temp = {};
        for(int i =0;i<points.size()-1;i++){
            cv::Point2f point = points[i] + (points[i+1] - points[i]) * t;
            temp.push_back(point);
        }
        points = temp;
    }
    return points[0];

}
        bezier
void bezier(const std::vector<cv::Point2f> &control_points, cv::Mat &window) 
{
    for (double t = 0.0; t <= 1.0; t += 0.001) 
    {
        cv::Point2f point = recursive_bezier(control_points,t);
        window.at<cv::Vec3b>(point.y, point.x)[2] = 255;
    }

}

提高

        反走样

        这里考虑周围的3*3空间,每个像素点的中心点到该点的距离。可以很容易得出,最大距离为3√3/2,最短距离为0,因此可以按照这个比例,求出每个像素点到该点的距离后,再根据距离计算颜色的权重。(因为有一些像素会被重复计算,因此为了实现反走样,新的像素颜色要和老的像素颜色比较,取最大值。)

void bezier(const std::vector<cv::Point2f> &control_points, cv::Mat &window)
{

    const float maxd = 3 * std::sqrt(2) / 2.0;
    for (double t = 0.0; t <= 1.0; t += 0.001)
    {
        cv::Point2f point = recursive_bezier(control_points, t);
        int pointx = (int)point.x;
        int pointy = (int)point.y;
        for (int i = -1; i <= 1; i++)
        {
            for (int j = -1; j <= 1; j++)
            {
                float x2 = std::pow(pointx + j - (point.x), 2);
                float y2 = std::pow(pointy + i - (point.y), 2);
                float d = std::sqrt(x2 + y2);
                window.at<cv::Vec3b>(point.y + i, point.x + j)[1] = std::fmax(255 * (1 - d / maxd), window.at<cv::Vec3b>(point.y + i, point.x + j)[1]);
            }
        }
    }
}

结果

正常的曲线

放大可以看到明显的锯齿

采用反走样的曲线

放大后可以看到平滑了很多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值