games 101 作业4

news2024/12/25 1:20:31

games 101 作业4

      • 题目
      • 题解
      • 作业答案

题目

Bézier 曲线是一种用于计算机图形学的参数曲线。在本次作业中,你需要实
现 de Casteljau 算法来绘制由 4 个控制点表示的 Bézier 曲线 (当你正确实现该
算法时,你可以支持绘制由更多点来控制的 Bézier 曲线)。
你需要修改的函数在提供的 main.cpp 文件中。
• bezier:该函数实现绘制 Bézier 曲线的功能。它使用一个控制点序列和一个
OpenCV::Mat 对象作为输入,没有返回值。它会使 t 在 0 到 1 的范围内进
行迭代,并在每次迭代中使 t 增加一个微小值。对于每个需要计算的 t,将
调用另一个函数 recursive_bezier,然后该函数将返回在 Bézier 曲线上 t
处的点。最后,将返回的点绘制在 OpenCV ::Mat 对象上。
• recursive_bezier:该函数使用一个控制点序列和一个浮点数 t 作为输入,
实现 de Casteljau 算法来返回 Bézier 曲线上对应点的坐标。
De Casteljau 算法说明如下:

  1. 考虑一个 p0, p1, … pn 为控制点序列的 Bézier 曲线。首先,将相邻的点连接
    起来以形成线段。
  2. 用 t : (1 − t) 的比例细分每个线段,并找到该分割点。
  3. 得到的分割点作为新的控制点序列,新序列的长度会减少一。
  4. 如果序列只包含一个点,则返回该点并终止。否则,使用新的控制点序列并
    转到步骤 1。
    使用 [0,1] 中的多个不同的 t 来执行上述算法,你就能得到相应的 Bézier 曲
    线

提升部分
实现对 Bézier 曲线的反走样。(对于一个曲线上的点,不只把它对应于一个像
素,你需要根据到像素中心的距离来考虑与它相邻的像素的颜色。)

题解

本次作业的难度适中,用递归的方式实现n次贝塞尔曲线。

根据算法说明以及贝塞尔函数的定义,实现如下算法:给定若干个点和t,返回这若干个控制点构成的贝塞尔曲线中t时刻的点。

cv::Point2f recursive_bezier(const std::vector<cv::Point2f> &control_points, float t) 
{
    if (control_points.size() == 1)
        return control_points[0];
    std::vector<cv::Point2f> new_control_points;
    for (int i = 0; i < control_points.size() -1; i++)
    {
        cv::Point2f p = t * control_points[i] + (1 - t) * control_points[i + 1];
        new_control_points.emplace_back(p);
    }
    return recursive_bezier(new_control_points,t);
}

然后t 从0到1,步进值可自定义,本代码中设置为0.001,也就是一条贝塞尔由1001个点组成,每个点的G通道设置为255,也就是线条颜色为绿色。

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.

    int neighborXIndex[8] = { 0,1,0,-1,-1,1,-1,1};
    int neighborYIndex[8] = { 1,0,-1,0.1,1,-1,-1};
    for (double t = 0.0; t <= 1.0; t += 0.001)
    {
        auto point = recursive_bezier(control_points,t);
        window.at<cv::Vec3b>(point.y, point.x)[1] = 255;
    }
}

提升:抗锯齿
根据点的位置到所在像素中心点距离,以及到相邻像素中心点的距离,计算相邻像素的颜色值。(可以是四邻或者八邻,下面以四邻距离说明)
在这里插入图片描述
假设当前像素Q点的颜色值为 c o l o r Q color_{Q} colorQ
则ABCD的颜色值分别为
c o l o r A = ∣ P Q ∣ / ∣ P A ∣ ∗ c o l o r Q color_{A}=|PQ|/|PA| * color_{Q} colorA=PQ∣/∣PAcolorQ
c o l o r B = ∣ P Q ∣ / ∣ P B ∣ ∗ c o l o r Q color_{B}=|PQ|/|PB| * color_{Q} colorB=PQ∣/∣PBcolorQ
c o l o r C = ∣ P Q ∣ / ∣ P C ∣ ∗ c o l o r Q color_{C}=|PQ|/|PC| * color_{Q} colorC=PQ∣/∣PCcolorQ
c o l o r D = ∣ P Q ∣ / ∣ P D ∣ ∗ c o l o r Q color_{D}=|PQ|/|PD| * color_{Q} colorD=PQ∣/∣PDcolorQ
代码如下:

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.

    int neighborXIndex[4] = { 0,1,0,-1};
    int neighborYIndex[4] = { 1,0,-1,0};
    for (double t = 0.0; t <= 1.0; t += 0.001)
    {
        auto point = recursive_bezier(control_points,t);
        window.at<cv::Vec3b>(point.y, point.x)[1] = 255;
        int x = point.x;
        int y = point.y;
        cv::Point2f p1(x + 0.5, y + 0.5);
        float d1 = std::sqrt(std::pow(point.x - p1.x, 2) + std::pow(point.y - p1.y, 2));

        for (int i = 0; i < 4; i++)
        {
            cv::Point2f p(x+ neighborXIndex[i]*0.5,y+ neighborYIndex[i]*0.5);
            float d = std::sqrt(std::pow(point.x - p.x, 2) + std::pow(point.y - p.y, 2));
            window.at<cv::Vec3b>(y + neighborYIndex[i], x + neighborXIndex[i])[1] = d1 / d * 255;
        }
    }

}

总结
贝塞尔函数的定义比较简单,n次贝塞尔的函数的定义公式如下:
B ( t ) = ∑ i = 0 n ( n i ) P i ( 1 − t ) n − i 1 t i B(t)=\sum_{i=0}^n\binom{n}{i} P_i(1-t)^{n-i_1} t^i B(t)=i=0n(in)Pi(1t)ni1ti
所以也可以不用递归,而是通过这个公式实现N次贝塞尔函数。
一条贝塞尔打断成两端贝塞尔,同时保持断点初过渡平滑,可以参考博文

作业答案

本次作业的答案放在的git仓库中:作业地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1698195.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vulnhub靶机De-ICE_S2.100_(de-ice.net-2.100-1.0)

下载地址&#xff1a;https://download.vulnhub.com/deice/De-ICE_S2.100_%28de-ice.net-2.100-1.0%29.iso 靶机搭建 注意下载下来的是iso文件接下来说明系统选择 linux的Debian 7.x就可以 然后注意一点我们需要创建一个192.168.2.0/24的网卡进行连接&#xff08;靶机ip地址…

ISCC2024个人挑战赛WP-DLLCode

&#xff08;非官方解&#xff0c;以下内容均互联网收集的信息和个人思路&#xff0c;仅供学习参考&#xff09; 注意到程序调用了Encode函数对明文进行加密&#xff0c;点进去发现是对外部DLL的调用 静态分析DLL中的Encode函数可以得到 写出对应的解密脚本如下 #include <…

SQL常用基础语句(一)-- ABCDE开头

AS 将列名从 count(*) 修改为 total select count(*) as total from users where status0 将列名 username 改为 uname&#xff0c; password 改为 upwd select username as uname, password as upwd from users BETWEEN AND 说明&#xff1a;BETWEEN 筛选的是 >value1且 &l…

澳大利亚.德国-门户媒体投放通稿:需要注意什么地方

概述 在现代社会&#xff0c;新闻媒体的投放成为企业和组织宣传推广的重要手段之一。澳大利亚和德国作为全球重要的经济和科技中心&#xff0c;其新闻媒体也备受关注。本文将介绍澳大利亚和德国的一些主要新闻媒体&#xff0c;并讨论发表新闻稿时需要注意的地方。 澳大利亚媒…

驱动开发之字符设备开发

1.概念 字符设备是 Linux 驱动中最基本的一类设备驱动&#xff0c;字符设备就是一个一个字节&#xff0c;按照字节 流进行读写操作的设备&#xff0c;读写数据是分先后顺序的。比如我们最常见的点灯、按键、IIC、SPI&#xff0c; LCD 等等都是字符设备&#xff0c;这些设备的驱…

OFDM通信中的部分内容

纠错编码&#xff1a;在无线通信过程中由于传输过程存在噪声等各种非理想因素&#xff0c;在接收端接收到的信息往往相对于发射信息存在误码&#xff0c;通过纠错编码方式可以对少数非连续的误码进行判断和纠正。举个简单的例子&#xff0c;发射端可能发射的信息为00,01,10,11,…

功率电感设计方法2:实例

文章目录 1&#xff1a;美磁的选项手册截图2&#xff1a;设计步骤2.1&#xff1a;设计需求2.2:选择磁芯材料2.3&#xff1a;选择磁芯2.4 查询 A L A_{L} AL​自感系数2.5 初算匝数2.6重新校准验算感量 3&#xff1a;后续 绕线因子4&#xff1a;日常壁纸分享 参考手册链接 1&…

HTML+CSS+JS(web前端大作业)~致敬鸟山明简略版

HTMLCSSJS【动漫网站】网页设计期末课程大作业 web前端开发技术 web课程设计 文章目录 一、网站题目 二、网站描述 三、网站介绍 四、网站效果 五、 网站代码 文章目录 一、 网站题目 动漫网站-鸟山明-龙珠超 二、 网站描述 页面分为页头、菜单导航栏&#xff08;最好可下拉&…

Denoising Diffusion Probabilistic Models 全过程概述 + 论文总结

标题&#xff1a;Denoising&#xff08;&#x1f31f;去噪&#xff09;Diffusion Probabilistic Models&#xff08;扩散概率模型&#xff09; 论文&#xff08;NeurIPS会议 CCF A 类&#xff09;&#xff1a;Denoising Diffusion Probabilistic Models 源码&#xff1a;hojona…

大数据智慧消防解决方案(24页PPT)

方案介绍&#xff1a; 大数据智慧消防解决方案是提升消防安全管理水平、保障人民群众生命财产安全的重要手段。通过集成物联网、云计算、大数据、人工智能等先进技术&#xff0c;构建集监测、预警、指挥、救援于一体的智慧消防系统&#xff0c;将为消防安全事业注入新的活力。…

ubuntu20.04安装cmake3.22.1

背景 由于第一套上位机windows clion22 嵌入式ubuntu20.04的开发环境中&#xff0c;ubuntu20.04上安装的是cmake3.22.1, 为了保持一致&#xff0c;需要指定安装的cmake版本。 下载指定版本的cmake 进入cmake官网的download页面&#xff0c;https://cmake.org/download/&…

加拿大媒体广告投放:媒体宣发主流媒体《金融邮报》《埃德蒙顿日报》

介绍《埃德蒙顿日报》与《埃德蒙顿太阳报》 在加拿大阿尔伯塔省首府埃德蒙顿&#xff0c;有两份主流新闻类报纸。其中&#xff0c;《埃德蒙顿日报》是加拿大主要英文报纸之一&#xff0c;也被称为爱蒙顿新闻报。而另一份报纸则是《埃德蒙顿太阳报》&#xff0c;是加拿大阿尔伯…

【Qt】深入探索Qt窗口与对话框:从创建到管理:QDockWidget(浮动窗口)、QDialog(对话框)

文章目录 前言&#xff1a;1. 浮动窗口2. 对话框介绍2.1. 示例&#xff1a;主窗口中&#xff0c;通过点击按钮&#xff0c;弹出一个新的对话框。2.2. 创建自定义对话框2.2.1. 纯代码的方式2.2.2. 图形化界面的方式 3. 模态对话框 和 非模态对话框4. Qt 内置对话框4.1. 消息对话…

【vue-cli搭建vue项目的过程2.x】

vue-cli搭建vue项目 vue-cli搭建vue项目安装node安装vue-cli脚手架并创建项目安装 Ant Design Vue或element-ui(笔者使用Ant-design-vue组件&#xff0c;并全局引入)开发安装三方库包1、Package.json文件---引入如下package.json文件执行npm i或npm install命令即可下载如下依赖…

Dou音滑块日志分析

记得加入我们的学习群&#xff1a;961566389 点击链接加入群聊&#xff1a;[https://h5.qun.qq.com/s/62P0xwrCNO](https://h5.qun.qq.com/s/62P0xwrCNO) 1.插桩-打印日志 获取背景和滑块的图片的接口一看没啥参数需要逆向的 验证的接口body参数需要进行逆向&#xff0c;直接…

Qt 界面上控件自适应窗体大小 - 随窗体缩放

Qt 界面上控件自适应窗体大小 - 随窗体缩放 引言一、在Qt Designer上设置二、参数详解三、参考链接 引言 添加布局&#xff0c;设置控件的minimumSize、maximumSize和sizePolicy可以使其跟随窗体进行自适应缩放 - 如上图所示。 一、在Qt Designer上设置 在代码中设置效果一致…

Slash后台管理系统代码阅读笔记 如何实现环形统计图表卡片?

目前&#xff0c;工作台界面的上半部分已经基本梳理完毕了。 接下来&#xff0c;我们看看这个环形图卡片是怎么实现的&#xff1f; 具体代码如下&#xff1a; {/*图表卡片*/} <Row gutter{[16, 16]} className"mt-4" justify"center">{/*环形图表…

Android BACK键和HOME键应用差异详解

文章目录 1、应用层分析1.1 BACK键功能实现 1.2 HOME键功能实现 1.3 BACK键与HOME键的区别 2、系统层分析2.1 BACK键的处理2.2 HOME键的处理2.3 代码分析BACK键HOME键BACK键的系统代码分析HOME键的系统代码分析BACK键HOME键 3、优缺点分析3.1 BACK键3.2 HOME键 4、项目中的使用…

ISCC2024个人挑战赛WP-迷失之门

&#xff08;非官方解&#xff0c;以下内容均互联网收集的信息和个人思路&#xff0c;仅供学习参考&#xff09; 迷失之门 方法一&#xff1a; IDA看一下 check函数逻辑 进入到check2函数 R键将ascii码转字符&#xff0c;写出逆向脚本 #include <stdio.h> #include &l…

【CCIE | 网络模拟器】部署 EVE-NG

目录 1. 环境准备2. 下载 EVE-NG 镜像3. 安装 EVE-NG 虚拟机3.1 创建 eve-ng 虚拟机3.2 选择存储3.3 定义虚拟机计算资源&#xff08;1&#xff09;开启CPU虚拟化功能&#xff08;2&#xff09;精简置备磁盘 3.4 检查虚拟机设置 4. 安装系统4.1 选择系统语言4.2 选择系统键盘类…