GAMES101-Assignment4

news2024/11/15 11:42:51

一、问题总览

实现de Casteljau算法来绘制由4个控制点表示的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曲线上对应点的坐标。

二、参考答案

2.1 算法思想

De Casteljau 算法说明如下:

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

使用[0,1] 中的多个不同的t来执行上述算法

  • 例子如下
    在这里插入图片描述

    • b 0 b_0 b0, b 1 b_1 b1, b 2 b_2 b2为三个参考点;
      • b 0 b 1 b_0b_1 b0b1 上找一点 b 0 1 b_0^1 b01,使得 b 0 b 0 1 b_0b_0^1 b0b01 : b 0 1 b 1 b_0^1b_1 b01b1 = t : (1 - t)
      • b 1 1 b_1^1 b11 同理
    • b 0 1 b_0^1 b01 b 1 1 b_1^1 b11 作为新的参考点,找点 b 0 2 b_0^2 b02,使比例关系满足t : (1 - t)
    • b 0 2 b_0^2 b02 就是贝塞尔曲线上的一点,使用[0,1] 中的多个不同的t来执行上述算法

2.2 代码实现

2.2.1 Bezier函数的实现

  • t=0 -> t=1, 调用de Casteljau算法
//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;
    }
}

2.2.2 Recursive_bezier函数的实现

  • 实现de Casteljau 算法来返回Bézier曲线上对应点的坐标
//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);
}

2.2.3 实现对贝塞尔曲线的反走样(奖励分数)

  • 对于一个曲线上的点,不只把它对应于一个像
    素,需要根据到像素中心的距离来考虑与它相邻的像素的颜色
    在这里插入图片描述

    • P是贝塞尔曲线上t对应的一点,P0是周围四个像素区域的交点,像素框的中心点为其余四个黑点
    • 像素外框都是处于window矩阵整数部分(默认一个window单元格为一个像素),所以p所在的像素框的较近一竖边为min(floor(p.x), ceil(p.x)),横边min(floor(p.y), ceil(p.y))
      • 计算出p0坐标( min(floor(p.x), ceil(p.x)),min(floor(p.y), ceil(p.y)) )
    • 由于像素框大小为1 * 1,所以知道P0之后可以计算出周围四个像素中心点坐标
    • 根据像素中心点到P点的距离来分配颜色
      • 比如距离p点距离为dist,则该点所在像素的G通道 = 255 * (3 - dist)/3
        • 使用的是哈夫曼距离,p离像素中心点最大哈夫曼距离为3
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  

通过点击屏幕来设置控制点


附件

作业4连接

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

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

相关文章

Java中什么序列化?

在Java中&#xff0c;序列化是一种将对象转换为字节序列的机制&#xff0c;使得对象可以在网络上传输或存储到文件中&#xff0c;而后可以通过反序列化还原为对象。Java提供了java.io.Serializable接口&#xff0c;通过实现这个接口的类可以实现对象的序列化和反序列化。 序列…

翻译:Building Efficient RAG Systems: A Deep Dive into devv.ai

RAG 的全称是&#xff1a;Retrieval Augmented Generation&#xff08;检索增强生成&#xff09; 最初来源于 2020 年 Facebook 的一篇论文&#xff1a;Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks&#xff08;是的&#xff0c;你没有看错&#xff0c;…

springboot学生综合测评系统源码和论文

随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;学生综合测评系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;学校规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人工管理显然已无法应对时代的变化&#xff0c;而…

将mask的图片标签转换为yolo的txt标签

将mask的图片标签转换为yolo的txt标签 获取外轮廓 import copy import cv2 import os import shutil import numpy as nppath "你的mask路径 /Dataset/mask" files os.listdir(path) for file in files:name file.split(.)[0]file_path os.path.join(path,name.…

市场复盘总结 20240109

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 昨日主题投资 连板进级率 66% 二进三&#xff1a; 进级率低 最常用的二种方法&#xff1a; 方法一&#x…

阿里巴巴秋招前端笔试题

单选题 下面的 JSX 代码中&#xff0c;哪一个无法达到预期的效果&#xff1f; A.<h2>Hello World</h2> B.<input type”checkbox”/> C.<div class”msg-box”>{msg}</div> D.<label htmlFor”name”>Leo</label> E.div styl…

编码技巧(二) element-ui table中根据状态控制是否可以勾选

项目中使用element-ui时,表格中的数据有不同的状态,需要对某个状态的数据进行 勾选操作 如图所示: 只有id为12的符合条件可以进行勾选 <el-table-column type="selection" header-align="center" :selectable="selectable" align="c…

Excel:通过excel将表数据批量转换成SQL语句

这里有一张表《student》&#xff0c;里面有10条测试数据&#xff0c;现在将这10条测试数据自动生成 insert语句&#xff0c;去数据库 批量执行 P.S. 主要用到excel表格中的 CONCATENATE函数&#xff0c;将单元格里面的内容填入到sql里面对应的位置 1. 先写好一条insert语句&a…

U盘、硬盘无法打开,修复RAW磁盘或分区,硬盘变成raw格式如何恢复,数据恢复

本文持续更新&#xff0c;针对遇到的数据丢失问题进行详细记录 磁盘变成RAW的可能原因 突然断电或关机文件系统丢失或损坏病毒或恶意软件感染坏扇区磁盘损坏 以下解决方案针对非病毒损坏 通过Windows自带的工具进行恢复&#xff08;CHKDSK命令&#xff09; 1.连接硬盘 2.…

资产信息管理系统-前后端开发

题目要求&#xff1a; 资产管理系统 利用H5规范&#xff0c;CSS样式与JS脚本独立于HTML页面&#xff0c;Javascript调用jQuery库&#xff0c;CRUD后端使用FastAPI封装&#xff0c;前端页面在Nginx中运行&#xff0c;调用API模块&#xff0c; 实现CURD的课设总结 基本设计&am…

java: 5-4 while循环 + do while循环

文章目录 1. while循环1.1 基本语法1.2 流程图1.3 上手练习1.4 细节1.5 练习题 2. do while 循环2.1 基本语法2.2 流程图2.3 上手练习2.4 细节2.5 练习题 【老韩b站视频笔记p126-p132】 1. while循环 1.1 基本语法 1.2 流程图 1.3 上手练习 输出 10 句 你好,韩顺平教育。 pu…

MySQL之导入导出远程备份(详细讲解)

文章目录 一、Navicat导入导出二、mysqldump命令导入导出2.1导出2.2导入&#xff08;使用mysqldump导入 包含t_log表的整个数据库&#xff09; 三、LOAD DATA INFILE命令导入导出3.1设置;3.2导出3.3导入(使用单表数据导入load data infile的方式) 四、远程备份4.1导出4.2导入 一…

一个大场景下无线通信仿真架构思路(对比omnet与训练靶场)

2020年分析过omnet的源码&#xff0c;读了整整一年&#xff0c;读完之后收获不小&#xff0c;但是也遗憾的发现这个东西只适合实验室做研究的人用于协议的研发与测试&#xff0c;并不适合大场景&#xff08;军事游戏等&#xff09;的应用&#xff0c;因为其固有架构更侧重于每个…

国产系统-银河麒麟桌面版安装wps

0安装版本 系统版本 版本名称:银河麒麟桌面版操作系统V10(SP1) 软件版本 wps个人版2019 1双击安装 1.1卸载自带wps 为什么要卸载没有序列号,授权过期,不是免费的,通过先安装/在升级个人版跳过输入序列号问题等等原因 1.1.1当前自带的wps版本 1.1.2卸载 不卸载无法安装在…

盖子的c++小课堂——第二十三讲:背包问题

前言 又是一次漫长的更新&#xff08;我真不是故意的aaaaaaaaaaaaaaa&#xff09;&#xff0c;先不多说了&#xff0c;直接给我~坐下~说错了说错了&#xff0c;直接开始~ 背包问题----动态规划 背包问题&#xff08;knapsack problem&#xff09; 动态规划&#xff08;dyna…

2024年中国电子学会青少年编程等级考试安排的通知

各有关单位、全体考生: 中国电子学会青少年等级考试&#xff08;以下简称等级考试&#xff09;是中国电子学会为落实《全民科学素质行动规划纲要》&#xff0c;提升青少年电子信息科学素质水平而开展的社会化评价项目。等级考试自2011年启动以来&#xff0c;作为中国电子学会科…

【野火i.MX6ULL开发板】在MobaXterm平台利用Type-C线串口连接开发板

0、前言 参考文献&#xff1a; http://t.csdnimg.cn/9iRTm http://t.csdnimg.cn/Z0n60 问题&#xff1a;一直识别不出com口&#xff0c; 拟解决思路&#xff1a; 百度网盘重新下载Debian镜像&#xff0c;烧入full版镜像&#xff0c;随便换一下USB插口&#xff08;电脑主机上…

SpringBoot 注解超全详解

使用注解的优势&#xff1a; 采用纯java代码&#xff0c;不在需要配置繁杂的xml文件 在配置中也可享受面向对象带来的好处 类型安全对重构可以提供良好的支持 减少复杂配置文件的同时亦能享受到springIoC容器提供的功能 1 注解详解&#xff08;配备了完善的释义&#xff0…

探索人工智能:深度学习、人工智能安全和人工智能

深度学习是人工智能的一种重要技术&#xff0c;它模拟了人类大脑神经网络的工作原理&#xff0c;通过建立多层次的神经元网络来实现对数据的分析和处理。这种技术的引入使得人工智能的发展进入到了一个新的阶段。 现如今&#xff0c;深度学习在各个领域都有着广泛的应用。例如…

数据库的导入导出以及备份

1.数据库的导出和导入 一.navicat导入导出 导入&#xff1a;右键➡运行SQL文件 导出选&#xff1a;中要导出的表➡右键➡转储SQL文件➡数据和结构 mysqldump命 1. 进入navicat安装目录的bin目录&#xff0c;cmd打开命令窗口 2. mysql -u用户名 -p ➡ 输入密码 3. creat…