GAMES101(0~1作业)

搭建虚拟机环境

  1. 安装Oracle VM VirtualBox虚拟机,安装虚拟硬盘,配置Linux Ubuntu-64 bit系统,
  2. 启动虚拟机,发生冲突错误:
    1. 将Vmware虚拟设备取消挂起状态,关机
    2. 确保 Hyper-V 完全关闭:bcdedit /set hypervisorlaunchtype off
    3. 重启计算机
  3. 安装增强功能,未找到iso错误:ISO下载地址:Index of http://download.virtualbox.org/virtualbox
    1. 首先升级虚拟机版本置7.0.2
    2. 通过update Guest additions
    3. 最后安装增强功能
  4. 通过终端调用cmake编译文件,
    1. 使用硬盘中的vscode编写main.cpp
    2. 通过终端创建文件touch CMakeLists.txt
    3. 编写文件(作业框架里有)
    4. cmake编译目录
    5. make编译
    6. 执行运行程序
# 指定最低版本要求
cmake_minimum_required(VERSION 2.8.5)
# 项目名称
project(Hello)
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
#
find_package(Eigen3 REQUIRED)
include_directories(EIGEN3_INCLUDE_DIR)
# 添加源文件
add_executable(pa0 main.cpp)

 作业0:

题目

给定一个点 P=(2,1), 将该点绕原点先逆时针旋转 45◦,再平移 (1,2), 计算出 变换后点的坐标(要求用齐次坐标进行计算)。

首先为向量增加一个分量(1),将变换的值带入,SL:3*3的旋转(绕z) * 平移矩阵公式中,最后乘以具有3个分量的向量

    auto angle = 45 * 3.14 / 180.0f;Eigen::Matrix3f R_Mat3;R_Mat3 <<std::cos(angle),-std::sin(angle),0,std::sin(angle), std::cos(angle),0,0,0,1;Eigen::Matrix3f T_Mat3;T_Mat3 <<1,0,1,0,1,2,0,0,1;Eigen::Vector3f p(2.0f,1.0f,1.0f);auto result = T_Mat3 * R_Mat3* p;std::cout << result;

作业1(OpenCV,Eigen):

题目

在给定作业框架填写一个旋转矩阵get_model_matrix()和一个透视投影矩阵get_projection_matrix(),给定三维下三个 点 v0(2.0, 0.0, −2.0), v1(0.0, 2.0, −2.0), v2(−2.0, 0.0, −2.0), 你需要将这三个点的坐 标变换为屏幕坐标并在屏幕上绘制出对应的线框三角形

解:

旋转矩阵:就是利用绕z旋转矩阵公式

    double fangle = rotation_angle / 180 * MY_PI;Eigen::Matrix4f rotation;rotation << cos(fangle), -sin(fangle), 0, 0,sin(fangle), cos(fangle), 0, 0,0, 0, 1, 0,0, 0, 0, 1;model = rotation * model;

透视投影矩阵:同样带入公式即可

    Eigen::Matrix4f proj, ortho;proj << zNear, 0, 0, 0,0, zNear, 0, 0,0, 0, zNear + zFar, -zNear * zFar,0, 0, 1, 0;double w, h, z;h = zNear * tan(eye_fov / 2) * 2;w = h * aspect_ratio;z = zFar - zNear;ortho << 2 / w, 0, 0, 0,0, 2 / h, 0, 0,0, 0, 2 / z, -(zFar+zNear) / 2,0, 0, 0, 1;projection = ortho * proj * projection;
标题

提高部分题目:

在 main.cpp 中构造一个函数,该函数的作用是得到绕任意 过原点的轴的旋转变换矩阵。Eigen::Matrix4f get_rotation(Vector3f axis, float angle)

解:

很明显从函数参数可以看出应用的是罗德里格斯公式,所以这里其实就是带入公式

Eigen::Matrix4f get_rotation(Vector3f axis, float angle) {double fangle = angle / 180 * MY_PI;Eigen::Matrix4f I, N, Rod;Eigen::Vector4f axi;Eigen::RowVector4f taxi;axi << axis.x(), axis.y(), axis.z(), 0;I=Eigen::Matrix4f::Identity();N << 0, -axis.z(), axis.y(), 0,axis.z(), 0, -axis.x(), 0,-axis.y(), axis.x(), 0, 0,0, 0, 0, 1;Rod = cos(fangle) * I + (1 - cos(fangle)) * axi * axi.transpose() + sin(fangle) * N;Rod(3, 3) = 1;return Rod;
}

理解代码

对于c语言使用.h,.c的扩展名,而对于c++使用.h,hpp(为了区分 C 和 C++ 代码),.cpp扩展名

main.cpp:变换矩阵的计算,模拟了图形管线,旋转三角形的控制

int argc,命令行参数的个数 const char** argv |const char* argv[]是一个数组,每个元素都是指向常量字符的指针

为什么argv[2]没有解引用?因为std::cout 会自动将 const char* 解释为一个以 \0 结尾的字符串。

int main(int argc, const char** argv)//在运行是输入命令行参数
{float angle = 0;//摄像机角度bool command_line = false;//设置命令行开关std::string filename = "output.png";//字符串if (argc >= 3) {//当3个参数command_line = true;angle = std::stof(argv[2]); // -r by default//从命令行获取旋转角度if (argc == 4) {//当4个参数filename = std::string(argv[3]);//从命令行获取文件名}elsereturn 0;}rst::rasterizer r(700, 700);//光栅化器类的实例,传入视口大小Eigen::Vector3f eye_pos = {0, 0, 5};//相机未知std::vector<Eigen::Vector3f> pos{{2, 0, -2}, {0, 2, -2}, {-2, 0, -2}};//3个顶点std::vector<Eigen::Vector3i> ind{{0, 1, 2}};//顶点索引auto pos_id = r.load_positions(pos);//保存顶点auto ind_id = r.load_indices(ind);//保存索引int key = 0;//键盘输入int frame_count = 0;if (command_line) {//如果传入参数>=3r.clear(rst::Buffers::Color | rst::Buffers::Depth);r.set_model(get_model_matrix(angle));r.set_view(get_view_matrix(eye_pos));r.set_projection(get_projection_matrix(45, 1, 0.1, 50));r.draw(pos_id, ind_id, rst::Primitive::Triangle);cv::Mat image(700, 700, CV_32FC3, r.frame_buffer().data());image.convertTo(image, CV_8UC3, 1.0f);cv::imwrite(filename, image);return 0;}while (key != 27) {//非ECSr.clear(rst::Buffers::Color | rst::Buffers::Depth);//计算模型、视图和投影矩阵,并传入光栅化器中,光栅化器在屏幕上显示出变换的结果r.set_model(get_model_matrix(angle));r.set_view(get_view_matrix(eye_pos));r.set_projection(get_projection_matrix(45, 1, 0.1, 50));r.draw(pos_id, ind_id, rst::Primitive::Triangle);//绘制三角形cv::Mat image(700, 700, CV_32FC3, r.frame_buffer().data());image.convertTo(image, CV_8UC3, 1.0f);cv::imshow("image", image);//显示图像key = cv::waitKey(10);std::cout << "frame count: " << frame_count++ << '\n';if (key == 'a') {//逆时针旋转10angle += 10;}else if (key == 'd') {//顺时针旋转10angle -= 10;}}return 0;
}

rasterizer.hpp , rasterizer.cpp光栅器 | 渲染器,生成渲染器界面与绘制。 

rst::pos_buf_id rst::rasterizer::load_positions(const std::vector<Eigen::Vector3f> &positions) // 保存到
{auto id = get_next_id();        // 从0开始分配,每次调用后索引增加pos_buf.emplace(id, positions); // 存放到顶点数组中return {id};
}rst::ind_buf_id rst::rasterizer::load_indices(const std::vector<Eigen::Vector3i> &indices)
{auto id = get_next_id();ind_buf.emplace(id, indices);return {id};
}// Bresenham's line drawing algorithm,
// Bresenham算法,绘制线
// Code taken from a stack overflow answer: https://stackoverflow.com/a/16405254
void rst::rasterizer::draw_line(Eigen::Vector3f begin, Eigen::Vector3f end)
{/* 起点和终点坐标 */auto x1 = begin.x();auto y1 = begin.y();auto x2 = end.x();auto y2 = end.y();/* 颜色 */Eigen::Vector3f line_color = {255, 255, 255};/*x, y当前绘制的像素点的坐标,dx, dy直线在 x 和 y 方向上的增量,dx1, dy1用于计算偏移量,px, py用于确定下一个像素点的坐标 ,xe, ye: 用于循环控制,表示直线的终点*/int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i;dx = x2 - x1;dy = y2 - y1;dx1 = fabs(dx);dy1 = fabs(dy);px = 2 * dy1 - dx1;py = 2 * dx1 - dy1;if (dy1 <= dx1)/* 如果在y轴上的偏移量比x轴上要小,更趋向于水平线 */{if (dx >= 0)/* 从起点坐标开始 */{x = x1;y = y1;xe = x2;}else/* 从终点坐标开始 */{x = x2;y = y2;xe = x1;}Eigen::Vector3f point = Eigen::Vector3f(x, y, 1.0f);/* 创建起点 */set_pixel(point, line_color);/* 设置为白色 */for (i = 0; x < xe; i++)/* 通过迭代来逐步绘制直线的每个像素点。 */{x = x + 1;if (px < 0)/* 像素的 y 坐标不需要改变 */{px = px + 2 * dy1;/* 更新 px 的值 */}else{if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))/* 表示 y 方向向上移动 */{y = y + 1;}else/* 表示 y 方向向下移动。 */{y = y - 1;}px = px + 2 * (dy1 - dx1);/* 更新 px 的值 */}//delay(0);Eigen::Vector3f point = Eigen::Vector3f(x, y, 1.0f);/* 新的点绘制到屏幕上 */set_pixel(point, line_color);}}else{……}
}auto to_vec4(const Eigen::Vector3f &v3, float w = 1.0f) // 默认创建点,引入齐次坐标
{return Vector4f(v3.x(), v3.y(), v3.z(), w);
}void rst::rasterizer::draw(rst::pos_buf_id pos_buffer, rst::ind_buf_id ind_buffer, rst::Primitive type)
{if (type != rst::Primitive::Triangle){throw std::runtime_error("Drawing primitives other than triangle is not implemented yet!");}//2维数组auto &buf = pos_buf[pos_buffer.pos_id];/* 根据id访问实际数据,3个顶点的坐标 */auto &ind = ind_buf[ind_buffer.ind_id];/* 三个顶点的索引 */float f1 = (100 - 0.1) / 2.0;float f2 = (100 + 0.1) / 2.0;Eigen::Matrix4f mvp = projection * view * model; // MVPfor (auto &i : ind)//第一次为{0,1,2}{Triangle t;/* 三角形对象 *//* MVP变换 ,对3个顶点 */Eigen::Vector4f v[] = {mvp * to_vec4(buf[i[0]], 1.0f),mvp * to_vec4(buf[i[1]], 1.0f),mvp * to_vec4(buf[i[2]], 1.0f)};/* 遍历每个顶点,除齐次坐标 */for (auto &vec : v){vec /= vec.w();}/* 对每个顶点,分解为xyz,变换到视口,应用视口矩阵 */for (auto &vert : v){vert.x() = 0.5 * width * (vert.x() + 1.0);vert.y() = 0.5 * height * (vert.y() + 1.0);vert.z() = vert.z() * f1 + f2;}/* 为三角形设置数据 */for (int i = 0; i < 3; ++i){t.setVertex(i, v[i].head<3>());t.setVertex(i, v[i].head<3>());t.setVertex(i, v[i].head<3>());}// 设置颜色t.setColor(0, 255.0, 0.0, 0.0);t.setColor(1, 0.0, 255.0, 0.0);t.setColor(2, 0.0, 0.0, 255.0);rasterize_wireframe(t); // 绘制}
}void rst::rasterizer::rasterize_wireframe(const Triangle &t) // 绘制三角形
{draw_line(t.c(), t.a());/* abc为3个顶点 */draw_line(t.c(), t.b());draw_line(t.b(), t.a());
}void rst::rasterizer::set_model(const Eigen::Matrix4f &m) // 设置成员变量
{model = m;
}void rst::rasterizer::set_view(const Eigen::Matrix4f &v)
{view = v;
}void rst::rasterizer::set_projection(const Eigen::Matrix4f &p)
{projection = p;
}void rst::rasterizer::clear(rst::Buffers buff) // 清理颜色和深度缓冲区
{if ((buff & rst::Buffers::Color) == rst::Buffers::Color){std::fill(frame_buf.begin(), frame_buf.end(), Eigen::Vector3f{0, 0, 0});}if ((buff & rst::Buffers::Depth) == rst::Buffers::Depth){std::fill(depth_buf.begin(), depth_buf.end(), std::numeric_limits<float>::infinity());}
}rst::rasterizer::rasterizer(int w, int h) : width(w), height(h) // 根据宽高比设置帧缓冲大小和深度缓冲大小
{frame_buf.resize(w * h);depth_buf.resize(w * h);
}int rst::rasterizer::get_index(int x, int y) // 根据坐标求像素在缓冲区的序号
{return (height - y) * width + x;
}void rst::rasterizer::set_pixel(const Eigen::Vector3f &point, const Eigen::Vector3f &color) // 将屏幕像素点 (x, y) 设 为 (r, g, b) 的颜色,并写入相应的帧缓冲区位置。
{// old index: auto ind = point.y() + point.x() * width;if (point.x() < 0 || point.x() >= width ||point.y() < 0 || point.y() >= height)return;auto ind = (height - point.y()) * width + point.x();frame_buf[ind] = color;
}

Triangle.hpp, Triangle.cpp三角形数据 ,提供了数据设置的接口

class Triangle
{public:/*the original coordinates of the triangle, v0, v1, v2 in counter clockwise order*//*Per vertex values*//* 顶点,颜色,纹理坐标,法线 */Vector3f v[3]; Vector3f color[3];      // color at each vertex;Vector2f tex_coords[3]; // texture u,vVector3f normal[3];     // normal vector for each vertex// Texture *tex;Triangle();/* 返回三角形顶点坐标 */Eigen::Vector3f a() const { return v[0]; }Eigen::Vector3f b() const { return v[1]; }Eigen::Vector3f c() const { return v[2]; }void setVertex(int ind, Vector3f ver); /*set i-th vertex coordinates */void setNormal(int ind, Vector3f n);   /*set i-th vertex normal vector*/void setColor(int ind, float r, float g, float b); /*set i-th vertex color*/void setTexCoord(int ind, float s,float t); /*set i-th vertex texture coordinate*/std::array<Vector4f, 3> toVector4() const;
};#endif // RASTERIZER_TRIANGLE_H//cppTriangle::Triangle()/* 初始值都为0 */
{v[0] << 0, 0, 0;v[1] << 0, 0, 0;v[2] << 0, 0, 0;color[0] << 0.0, 0.0, 0.0;color[1] << 0.0, 0.0, 0.0;color[2] << 0.0, 0.0, 0.0;tex_coords[0] << 0.0, 0.0;tex_coords[1] << 0.0, 0.0;tex_coords[2] << 0.0, 0.0;
}void Triangle::setVertex(int ind, Eigen::Vector3f ver) { v[ind] = ver; }/* 设置指定索引的值 */void Triangle::setNormal(int ind, Vector3f n) { normal[ind] = n; }void Triangle::setColor(int ind, float r, float g, float b)/* 将颜色从0--255,转到0--1 */
{if ((r < 0.0) || (r > 255.) || (g < 0.0) || (g > 255.) || (b < 0.0) ||(b > 255.)) {throw std::runtime_error("Invalid color values");/* 超出范围抛出异常 */}color[ind] = Vector3f((float)r / 255., (float)g / 255., (float)b / 255.);return;
}
void Triangle::setTexCoord(int ind, float s, float t)
{tex_coords[ind] = Vector2f(s, t);
}std::array<Vector4f, 3> Triangle::toVector4() const/* 三个顶点从 Vector3f 类型转换为 Vector4f 类型 */
{std::array<Vector4f, 3> res;std::transform(std::begin(v), std::end(v), res.begin(), [](auto& vec) {/* 遍历每个顶点 */return Vector4f(vec.x(), vec.y(), vec.z(), 1.f);});return res;
}

阅读复杂指针

如何阅读C/C++中的复杂的指针类型声明(源码中常遇到)_c++复杂阅读指针-CSDN博客

右左法则:从标识符开始,从右到左,优先级越高

括号法则:运算优先级更高

规律:普通变量(左边是本身类型),指针|引用(左边表示指向的类型),数组(左边表示元素类型),函数(左边表示返回类型)

int *  a  [10];a是一个包含10个数据的数组,每个元素是一个指向int的指针

int (*a) [3]; a是一个指针,指向3个元素的数组,每个元素是int类型

int *foo();foo是一个函数,返回指向int指针

int (*foo)();foo是一个指针,指向函数,函数返回int

int (*(*vtable)[])();vtable是一个指针,指向数组,每个元素是指针,并指向函数,函数返回类型为int

int name[] [n],name是一个数组,每个元素也是数组,包含n个int类型元素

const char** argv,argv是一个指针,指向常量字符的指针

const char* argv[]argv是一个数组,每个元素都是指向常量字符的指针

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

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

相关文章

【Python · Pytorch】配置cuda环境 cuDNN库

【Python Pytorch】配置cuda环境 & cuDNN库 1. 查找对应版本1.1 查看Pytorch GPU目前支持版本1.1 查看Nvidia驱动版本1.2 查看支持cuda版本1.3 查看支持cuDNN版本1.3.1 cuDNN 9.0.0及以上版本1.3.2 cuDNN 9.0.0以下版本 1.4 安装版本确定 2. 安装cuda环境2.1 cuda简介2.1.…

Leetcode Hot 100刷题记录 -Day10(合并区间)

合并区间 问题描述&#xff1a; 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti,endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&…

【计算机网络】浏览器输入访问某网址时,后台流程是什么

在访问网址时&#xff0c;后台的具体流程可以因不同的网站、服务器和应用架构而异。 实际过程中可能还涉及更多的细节和步骤&#xff0c;如缓存处理、重定向、负载均衡等。 此外&#xff0c;不同的网站和应用架构可能会有不同的实现方式和优化策略。 部分特定网站或应用&#x…

【C++】stack、queue、priority_queue的模拟实现

目录 一、stack &#x1f31f;stack的简单介绍 &#x1f31f;stack的基本使用 &#x1f31f;stack的模拟实现 &#x1f31f;stack模拟实现的完整代码 &#x1f31f;容器适配器 二、queue &#x1f31f;queue的简单介绍 &#x1f31f;queue的基本使用 &#x1f31f;q…

828华为云征文|Flexus云服务器X实例快速部署在线测评平台,适用各种信息学教学

文章目录 如何选配Flexus云服务器X实例服务器HydroOJHOJ 服务器资源的选取基础配置实例规格镜像、存储、网络弹性公网IP云服务器名称 部署HydroOJ1.设置安全组、开放端口2.部署HydroOJ回到控制中心&#xff0c;远程登录 部署HOJ安装docker# 安装docker-compose部署HOJ 本篇幅为…

Git 使用指南 --- 版本管理

序言 Git 是一个开源的 分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。对一个程序员来说&#xff0c;掌握 Git 的使用是必要的。  在这个系列中&#xff0c;将详细的介绍 Git 的使用和原理&#xff0c;话不多说&#xff0c;让我们开始吧。…

【C++ 面试 - STL】每日 3 题(四)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

qiankun微前端

qiankun微前端踩坑指南&#xff1a; 上图原因子项目未启动 上图使用$tqiankun微前端中未引用i18n插件解决方案如下&#xff1a; 子项目main.js中加上i18n: 一些坑忘记截图复现会继续更新....... 配置正文开始------> 主项目 子项目 1.名字需要与子项目跳转后缀一致 2.v…

景联文科技:提供高质量多模态数据标注,推动智能化转型

随着人工智能技术的快速发展&#xff0c;多模态数据标注成为推动智能系统更深层次理解和应用的关键技术之一。 作为行业领先的多模态数据标注服务商&#xff0c;景联文科技凭借其在技术、流程和人才方面的综合优势&#xff0c;推出了全面的多模态标注解决方案&#xff0c;助力…

Python | Leetcode Python题解之第392题判断子序列

题目&#xff1a; 题解&#xff1a; class Solution:def isSubsequence(self, s: str, t: str) -> bool:n, m len(s), len(t)f [[0] * 26 for _ in range(m)]f.append([m] * 26)for i in range(m - 1, -1, -1):for j in range(26):f[i][j] i if ord(t[i]) j ord(a) el…

【5G PHY】5G循环前缀(CP)设计思路简述

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G技术研究。 博客内容主要围绕…

将语义分割的标签转换为实例分割(yolo)的标签

语义分割的标签&#xff08;目标处为255&#xff0c;其余处为0&#xff09; 实例分割的标签&#xff08;yolo.txt&#xff09;,描述边界的多边形顶点的归一化位置 绘制在原图类似蓝色的边框所示。 废话不多说&#xff0c;直接贴代码&#xff1b; import os import cv2 imp…

监控平台总结之面试常问答案

思路 延伸的面试题总结及答案&#xff1a; 1.说说前端监控平台/监控SDK架构设计和难点亮点&#xff1f; 架构设计 数据采集层: SDK: 在前端集成的 SDK 负责采集数据&#xff0c;包括性能指标、用户行为、错误日志等。 数据收集: 实现高效的数据采集机制&#xff0c;支持实时…

分类任务实现模型集成代码模版

分类任务实现模型&#xff08;投票式&#xff09;集成代码模版 简介 本实验使用上一博客的深度学习分类模型训练代码模板-CSDN博客&#xff0c;自定义投票式集成&#xff0c;手动实现模型集成&#xff08;投票法&#xff09;的代码。最后通过tensorboard进行可视化&#xff0…

傅里叶变换家族

禹晶、肖创柏、廖庆敏《数字图像处理&#xff08;面向新工科的电工电子信息基础课程系列教材&#xff09;》 禹晶、肖创柏、廖庆敏《数字图像处理》资源二维码

java设计模式(行为型模式:状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式)

6&#xff0c;行为型模式 6.5 状态模式 6.5.1 概述 【例】通过按钮来控制一个电梯的状态&#xff0c;一个电梯有开门状态&#xff0c;关门状态&#xff0c;停止状态&#xff0c;运行状态。每一种状态改变&#xff0c;都有可能要根据其他状态来更新处理。例如&#xff0c;如果…

太细了有手就行,SpringCloud Alibaba+Nacos+Dubbo整合

SpringCloud AlibabaNacosDubbo&#xff0c;文末有完整项目代码链接 前言一、这几者之间关系二、准备工作1.Nacos2.SpringCloud Alibaba4.SpringCloud5.Dubbo项目中层级关系 三、代码调用逻辑1.dubbo-api模块2.account-api模块3.api-service模块4.逻辑梳理 四、Maven和配置1.pa…

尽快更新!Zyxel 路由器曝出 OS 命令注入漏洞,影响多个版本

近日&#xff0c;Zyxel 发布安全更新&#xff0c;以解决影响其多款商用路由器的关键漏洞&#xff0c;该漏洞可能允许未经认证的攻击者执行操作系统命令注入。 该漏洞被追踪为 CVE-2024-7261&#xff0c;CVSS v3 得分为 9.8&#xff0c;是一个输入验证故障&#xff0c;由用户提…

了解PD快充协议和QC快充协议

PD快充协议的实现依赖充电器与设备之间的通信协议&#xff0c;这种通信协议确保了充电器能够提供设备所需要的特定电压和电流。在快充技术中快充协议起到关键角色。 现在市面上最常见的快充协议有PD、QC、华为FCP/SCP、三星AFC协议 、VOOC闪充。PD和QC 协议属于公用协议 。华…

CSS 高级区块效果——WEB开发系列25

CSS提供了多种工具和属性&#xff0c;使我们能够创建视觉上引人注目的效果。今天我们继续将深入了解几种高级CSS效果&#xff1a;盒子阴影、滤镜、混合模式和文本背景裁剪&#xff0c;提升网页设计的质感和深度。 一、盒子阴影&#xff08;Box Shadow&#xff09; 对于盒子元素…