当前位置: 首页 > news >正文

games101-作业3

由于此次试验需要加载模型,涉及到本地环节,如果是windows系统,需要对main函数中的路径稍作改变:

这么写需要:
#include "windows.h"

该段代码:


#include "windows.h"
int main(int argc, const char** argv)
{std::vector<Triangle*> TriangleList;float angle = 140.0;bool command_line = false;std::string filename = "output.png";objl::Loader Loader;std::string obj_path = "\\..\\..\\test\\models\\spot\\";char pathBuf[MAX_PATH];char* p;if (GetModuleFileNameA(NULL, pathBuf, MAX_PATH)){p = strrchr(pathBuf, '\\');if (p){*p = '\0';std::string exe_path = pathBuf;obj_path = exe_path + obj_path;}}bool loadout = Loader.LoadFile("D:\\opencode\\games101\\test\\test\\models\\spot\\spot_triangulated_good.obj");

同时在windows下计算很卡,可能软件模拟计算量很大的原因;

使用c++17及以上版本,

\spot_triangulated_good.obj 中的描述了顶点信息

输入到三角形列表中: 

但是 在使用的时候:

fragment_shader 即下面的着色模型:中去如何消费这个图片


    std::function<Eigen::Vector3f(fragment_shader_payload)> active_shader = normal_fragment_shader;  用于设置着色模型

着色模型

1.normal模型
// 根据法线进行不同着色
Eigen::Vector3f normal_fragment_shader(const fragment_shader_payload& payload)
{Eigen::Vector3f return_color = (payload.normal.head<3>().normalized() + Eigen::Vector3f(1.0f, 1.0f, 1.0f)) / 2.f;Eigen::Vector3f result;result << return_color.x() * 255, return_color.y() * 255, return_color.z() * 255;return result;
}

这个函数并不是光照模型,只是根据不同法线返回不同颜色值。
第一行的代码,首先取出当前待着色像素点的法向量的X,Y,Z坐标并归一化,故此时X,Y,Z都在[-1,1]之间,加上(1.0f, 1.0f, 1.0f)后,变为[0,2],再除以2,即得[0,1],再分别乘以255即可得到各个颜色值了。

效果:

2.phong模型

Eigen::Vector3f phong_fragment_shader(const fragment_shader_payload& payload)
{// 泛光、漫反射、高光系数Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);Eigen::Vector3f kd = payload.color;Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);// 灯光位置和强度auto l1 = light{{20, 20, 20}, {500, 500, 500}};auto l2 = light{{-20, 20, 0}, {500, 500, 500}};std::vector<light> lights = {l1, l2};// 光照Eigen::Vector3f amb_light_intensity{10, 10, 10};// 环境光强度Eigen::Vector3f eye_pos{0, 0, 10};// 相机位置float p = 150;// ping point的信息Eigen::Vector3f color = payload.color;Eigen::Vector3f point = payload.view_pos;// view spaceEigen::Vector3f normal = payload.normal;Eigen::Vector3f result_color = {0, 0, 0};// 光照结果Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);// 遍历每一束光for (auto& light : lights){Eigen::Vector3f l = (light.position - point).normalized(), v = (eye_pos - point).normalized();// 光照方向和观察方向Eigen::Vector3f h = (l + v).normalized();// 半程向量Eigen::Vector3f I = light.intensity;// 光强float r2 = (light.position - point).dot(light.position - point);Eigen::Vector3f Ld = kd.cwiseProduct(I / r2) * std::max(0.0f, normal.dot(l));//cwiseProduct()函数允许Matrix直接进行点对点乘法,而不用转换至ArrayEigen::Vector3f Ls = ks.cwiseProduct(I / r2) * std::pow(std::max(0.0f, normal.dot(h)), p);result_color += La + Ld + Ls;}//Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);//result_color += La;return result_color * 255.f;
}

直接根据公式写就行,这里我认为环境光应该放在循环外,不过这样渲出来的结果相比说说明偏暗,但后面的displacement又要放在外面否则偏亮。

phong模型渲染结果:

3.texture模型
Eigen::Vector3f texture_fragment_shader(const fragment_shader_payload& payload)
{Eigen::Vector3f return_color = {0, 0, 0};if (payload.texture){return_color = payload.texture->getColor(payload.tex_coords.x(), payload.tex_coords.y());// 获取材质颜色信息}Eigen::Vector3f texture_color;texture_color << return_color.x(), return_color.y(), return_color.z();Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);Eigen::Vector3f kd = texture_color / 255.f;// 材质颜色影响漫反射系数Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);auto l1 = light{{20, 20, 20}, {500, 500, 500}};auto l2 = light{{-20, 20, 0}, {500, 500, 500}};std::vector<light> lights = {l1, l2};Eigen::Vector3f amb_light_intensity{10, 10, 10};Eigen::Vector3f eye_pos{0, 0, 10};float p = 150;Eigen::Vector3f color = texture_color;Eigen::Vector3f point = payload.view_pos;Eigen::Vector3f normal = payload.normal;Eigen::Vector3f result_color = {0, 0, 0};Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);for (auto& light : lights){Eigen::Vector3f l = (light.position - point).normalized(), v = (eye_pos - point).normalized();// 光照方向和观察方向Eigen::Vector3f h = (l + v).normalized();// 半程向量Eigen::Vector3f I = light.intensity;// 光强float r2 = (light.position - point).dot(light.position - point);Eigen::Vector3f Ld = kd.cwiseProduct(I / r2) * std::max(0.0f, normal.dot(l));//cwiseProduct()函数允许Matrix直接进行点对点乘法,而不用转换至ArrayEigen::Vector3f Ls = ks.cwiseProduct(I / r2) * std::pow(std::max(0.0f, normal.dot(h)), p);result_color += La + Ld + Ls;}// Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);// result_color += La;return result_color * 255.f;
}

 

    Eigen::Vector3f getColor(float u, float v){// 限制(u, v)坐标范围u = std::fmin(1, std::fmax(u, 0));v = std::fmin(1, std::fmax(v, 0));auto u_img = u * (width-1);auto v_img = (1 - v) * (height-1);auto color = image_data.at<cv::Vec3b>(v_img, u_img);// 四舍五入return Eigen::Vector3f(color[0], color[1], color[2]);}

更换一个材质:

4 displacement_fragment_shader 

Eigen::Vector3f displacement_fragment_shader(const fragment_shader_payload& payload)
{Eigen::Vector3f ka = Eigen::Vector3f(0.005, 0.005, 0.005);Eigen::Vector3f kd = payload.color;Eigen::Vector3f ks = Eigen::Vector3f(0.7937, 0.7937, 0.7937);auto l1 = light{{20, 20, 20}, {500, 500, 500}};auto l2 = light{{-20, 20, 0}, {500, 500, 500}};std::vector<light> lights = {l1, l2};Eigen::Vector3f amb_light_intensity{10, 10, 10};Eigen::Vector3f eye_pos{0, 0, 10};float p = 150;Eigen::Vector3f color = payload.color; Eigen::Vector3f point = payload.view_pos;Eigen::Vector3f normal = payload.normal;float kh = 0.2, kn = 0.1;float x = normal.x();float y = normal.y();float z = normal.z();Eigen::Vector3f t{ x * y / std::sqrt(x * x + z * z), std::sqrt(x * x + z * z), z*y / std::sqrt(x * x + z * z) };Eigen::Vector3f b = normal.cross(t);Eigen::Matrix3f TBN;TBN <<  t.x(), b.x(), normal.x(),t.y(), b.y(), normal.y(),t.z(), b.z(), normal.z();float u = payload.tex_coords.x();float v = payload.tex_coords.y();float w = payload.texture->width;float h = payload.texture->height;float dU = kh * kn * (payload.texture->getColor(u + 1 / w , v).norm() - payload.texture->getColor(u, v).norm());float dV = kh * kn * (payload.texture->getColor(u, v + 1 / h).norm() - payload.texture->getColor(u, v).norm());Eigen::Vector3f ln{-dU, -dV, 1};//与凹凸贴图的区别就在于这句话point += (kn * normal * payload.texture->getColor(u , v).norm());normal = (TBN * ln).normalized();Eigen::Vector3f result_color = {0, 0, 0};for (auto& light : lights){Eigen::Vector3f l = (light.position - point).normalized();      // 光Eigen::Vector3f v = (eye_pos - point).normalized();		        // 眼Eigen::Vector3f h = (l + v).normalized();                       // 半程向量double r_2 = (light.position - point).dot(light.position - point);Eigen::Vector3f Ld = kd.cwiseProduct(light.intensity / r_2) * std::max(0.0f, normal.dot(l));    //cwiseProduct()函数允许Matrix直接进行点对点乘法,而不用转换至Array。Eigen::Vector3f Ls = ks.cwiseProduct(light.intensity / r_2) * std::pow(std::max(0.0f, normal.dot(h)), p);result_color += (Ld + Ls);   }Eigen::Vector3f La = ka.cwiseProduct(amb_light_intensity);result_color += La; return result_color * 255.f;
}

 draw函数(顶点、三角形处理阶段) 

void rst::rasterizer::draw(std::vector<Triangle*>& TriangleList) {float f1 = (50 - 0.1) / 2.0;// zfar和znear距离的一半float f2 = (50 + 0.1) / 2.0;// zfar和znear的中心z坐标Eigen::Matrix4f mvp = projection * view * model;// 计算MVP变换矩阵// 遍历每个小三角形for (const auto& t : TriangleList){Triangle newtri = *t;// 计算viewspace_pos,其中viewspace_pos的坐标是经过MV变换,没有经过P投影变换// 所以默认在相机坐标系而不是世界坐标系// 记录三角形顶点MV变换后坐标std::array<Eigen::Vector4f, 3> mm{(view * model * t->v[0]),(view * model * t->v[1]),(view * model * t->v[2])};std::array<Eigen::Vector3f, 3> viewspace_pos;// 存入viewspace_posstd::transform(mm.begin(), mm.end(), viewspace_pos.begin(), [](auto& v) {return v.template head<3>();});// 得到经过mvp后的坐标Eigen::Vector4f v[] = {mvp * t->v[0],mvp * t->v[1],mvp * t->v[2]};// 换算齐次坐标for (auto& vec : v) {vec.x() /= vec.w();vec.y() /= vec.w();vec.z() /= vec.w();}// 计算在MV转换后各顶点的法向量// 利用原来点法向量推出MV变换后法向量// 因为光线作用是在view_space下进行的Eigen::Matrix4f inv_trans = (view * model).inverse().transpose();Eigen::Vector4f n[] = {inv_trans * to_vec4(t->normal[0], 0.0f),inv_trans * to_vec4(t->normal[1], 0.0f),inv_trans * to_vec4(t->normal[2], 0.0f)};// 视口变换 得到顶点在屏幕上的坐标 即screen spacefor (auto& vert : v){vert.x() = 0.5 * width * (vert.x() + 1.0);vert.y() = 0.5 * height * (vert.y() + 1.0);// 为了Zbuffer保留Z值// (透视)投影变换最后一步是从正交投影变换到正则立方体// 而这一步就是把正则立方体的z值还原到正交投影时的z值,即原始z值vert.z() = vert.z() * f1 + f2;}// 记录经过MVP视口变换后的顶点坐标// 完成顶点变换,变换到屏幕空间for (int i = 0; i < 3; ++i){//screen space coordinatesnewtri.setVertex(i, v[i]);}// 记录顶点的法向量for (int i = 0; i < 3; ++i){//view space normalnewtri.setNormal(i, n[i].head<3>());}// 设置颜色newtri.setColor(0, 148, 121.0, 92.0);newtri.setColor(1, 148, 121.0, 92.0);newtri.setColor(2, 148, 121.0, 92.0);// 对这个小三角形进行光栅化// 传入viewspace_pos的坐标,光线的作用是在viewspace下的rasterize_triangle(newtri, viewspace_pos);}
}
//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) 
{auto v = t.toVector4(); //v[0],v[1],v[2]分别为三角形的三个顶点,是四维向量//比较三个顶点的横纵坐标,确定包围盒的边界并取整double min_x = std::min(v[0][0], std::min(v[1][0], v[2][0]));double max_x = std::max(v[0][0], std::max(v[1][0], v[2][0]));double min_y = std::min(v[0][1], std::min(v[1][1], v[2][1]));double max_y = std::max(v[0][1], std::max(v[1][1], v[2][1]));min_x = static_cast<int>(std::floor(min_x));min_y = static_cast<int>(std::floor(min_y));max_x = static_cast<int>(std::ceil(max_x));max_y = static_cast<int>(std::ceil(max_y));//此处实现的是MSAAstd::vector<Eigen::Vector2f> pos{                               //对一个像素分割四份 当然你还可以分成4x4 8x8等等甚至你还可以为了某种特殊情况设计成不规则的图形来分割单元{0.25,0.25},                //左下{0.75,0.25},                //右下{0.25,0.75},                //左上{0.75,0.75}                 //右上};for (int i = min_x; i <= max_x; ++i){for (int j = min_y; j <= max_y; ++j){int count = 0; //开始遍历四个小格子,获得平均值for (int MSAA_4 = 0; MSAA_4 < 4; ++MSAA_4){if (insideTriangle(static_cast<float>(i+pos[MSAA_4][0]), static_cast<float>(j+pos[MSAA_4][1]),t.v))++count;}if(count) //至少有一个小格子在三角形内{//此处是框架中代码,获得z,见原程序注释://    * v[i].w() is the vertex view space depth value z.//    * Z is interpolated view space depth for the current pixel//    * zp is depth between zNear and zFar, used for z-bufferauto[alpha, beta, gamma] = computeBarycentric2D(i + 0.5, j + 0.5, t.v);float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();zp *= Z;//endif (depth_buf[get_index(i, j)] > zp){depth_buf[get_index(i, j)] = zp;//更新深度//这里注意,虽然说明上说"反转了z,保证都是正数,并且越大表示离视点越远",//但经过我的查看,实际上并没有反转,因此还是按照-z近大远小来做,当然也可以在上面补一个负号不过没必要//利用重心坐标插值各种值auto interpolated_color = interpolate(alpha, beta, gamma, t.color[0], t.color[1], t.color[2], 1);auto interpolated_normal = interpolate(alpha, beta, gamma, t.normal[0], t.normal[1], t.normal[2], 1).normalized();auto interpolated_texcoords = interpolate(alpha, beta, gamma, t.tex_coords[0], t.tex_coords[1], t.tex_coords[2], 1);auto interpolated_shadingcoords = interpolate(alpha, beta, gamma, view_pos[0], view_pos[1], view_pos[2], 1);//shadingcoords是由view_pos插值得到,也就是物体表面的点在相机坐标系的位置。他们会在shader中被用到,来计算光照等信息。//此处是框架中代码,获得z,见原程序注释:fragment_shader_payload payload(interpolated_color, interpolated_normal, interpolated_texcoords, texture ? &*texture : nullptr);payload.view_pos = interpolated_shadingcoords;auto pixel_color = fragment_shader(payload);//end// 设置颜色set_pixel(Eigen::Vector2i(i, j), pixel_color * (count / 4.0));}}}}
}

完整代码:vs2022

相关文章:

games101-作业3

由于此次试验需要加载模型&#xff0c;涉及到本地环节&#xff0c;如果是windows系统&#xff0c;需要对main函数中的路径稍作改变&#xff1a; 这么写需要&#xff1a; #include "windows.h" 该段代码&#xff1a; #include "windows.h" int main(int ar…...

【Block总结】高效多尺度注意力EMA,超越SE、CBAM、SA、CA等注意力|即插即用

论文信息 标题: Efficient Multi-Scale Attention Module with Cross-Spatial Learning 作者: Daliang Ouyang, Su He, Guozhong Zhang, Mingzhu Luo, Huaiyong Guo, Jian Zhan, Zhijie Huang 论文链接: https://arxiv.org/pdf/2305.13563v2 GitHub链接: https://github.co…...

Pwn 入门核心工具和命令大全

一、调试工具&#xff08;GDB 及其插件&#xff09; GDB 启动调试&#xff1a;gdb ./binary 运行程序&#xff1a;run 或 r 设置断点&#xff1a;break *0x地址 或 b 函数名 查看寄存器&#xff1a;info registers 查看内存&#xff1a;x/10wx 0x地址 &#xff08;查看 10 个 …...

探索AI(chatgpt、文心一言、kimi等)提示词的奥秘

大家好&#xff0c;我是老六哥&#xff0c;我正在共享使用AI提高工作效率的技巧。欢迎关注我&#xff0c;共同提高使用AI的技能&#xff0c;让AI成功你的个人助理。 "AI提示词究竟是什么&#xff1f;" 这是许多初学者在接触AI时的共同疑问。 "我阅读了大量关于…...

利用飞书机器人进行 - ArXiv自动化检索推荐

相关作者的Github仓库 ArXivToday-Lark 使用教程 Step1 新建机器人 根据飞书官方机器人使用手册&#xff0c;新建自定义机器人&#xff0c;并记录好webhook地址&#xff0c;后续将在配置文件中更新该地址。 可以先完成到后续步骤之前&#xff0c;后续的步骤与安全相关&…...

小白爬虫冒险之反“反爬”:无限debugger、禁用开发者工具、干扰控制台...(持续更新)

背景浅谈 小白踏足JS逆向领域也有一年了&#xff0c;对于逆向这个需求呢主要要求就是让我们去破解**“反爬机制”**&#xff0c;即反“反爬”&#xff0c;脚本处理层面一般都是decipher网站对request设置的cipher&#xff0c;比如破解一个DES/AES加密拿到key。这篇文章先不去谈…...

Ubuntu中MySQL安装-02

服务器端安装 安装服务器端&#xff1a;在终端中输入如下命令&#xff0c;回车后&#xff0c;然后按照提示输入 sudo apt-get install mysql-server 当前使用的ubuntu镜像中已经安装好了mysql服务器端&#xff0c;无需再安装&#xff0c;并且设置成了开机自启动服务器用于接…...

大数据相关职位介绍之一(数据分析,数据开发,数据产品经理,数据运营)

大数据相关职位介绍之一 随着大数据、人工智能&#xff08;AI&#xff09;和机器学习的快速发展&#xff0c;数据分析与管理已经成为各行各业的重要组成部分。从互联网公司到传统行业的数字转型&#xff0c;数据相关职位在中国日益成为推动企业创新和提升竞争力的关键力量。以…...

使用DeepSeek API生成Markdown文件

DeepSeek技术应用与代码实现 一、DeepSeek简介 DeepSeek是一款强大的人工智能写作助手&#xff0c;能够根据用户输入的提示&#xff08;Prompt&#xff09;快速生成高质量的文章。它不仅支持批量生成文章&#xff0c;还能通过智能分段、Markdown转HTML等功能优化内容。此外&…...

java多线程学习笔记

文章目录 关键词1.什么是多线程以及使用场景?2.并发与并行3.多线程实现3.1继承 Thread 类实现3.2Runnable 接口方式实现3.3Callable接口/Future接口实现3.4三种方式总结 4.常见的成员方法&#xff08;重点记忆&#xff09;94.1setName/currentThread/sleep要点4.2线程的优先级…...

Manticore Search,新一代搜索引擎之王

吊打ES&#xff0c;新一代搜索引擎之王 概述 Manticore Search 是一个开源的分布式搜索引擎&#xff0c;专注于高性能和低延迟的搜索场景。 它基于 Sphinx 搜索引擎开发&#xff0c;继承了 Sphinx 的高效索引和查询能力&#xff0c;并在分布式架构、实时搜索、易用性等方面进…...

【MySQL】数据类型与表约束

目录 数据类型分类 数值类型 tinyint类型 bit类型 小数类型 字符串类型 日期和时间类型 enum和set 表的约束 空属性 默认值 列描述 zerofill 主键 自增长 唯一键 外键 数据类型分类 数值类型 tinyint类型 MySQL中&#xff0c;整形可以是有符号和无符号的&…...

CAG技术:提升LLM响应速度与质量

标题&#xff1a;CAG技术&#xff1a;提升LLM响应速度与质量 文章信息摘要&#xff1a; CAG&#xff08;Cache-Augmented Generation&#xff09;通过预加载相关知识到LLM的扩展上下文中&#xff0c;显著减少了检索延迟和错误&#xff0c;从而提升了响应速度和质量。与传统的R…...

上位机知识篇---Linux源码编译安装链接命令

文章目录 前言第一部分&#xff1a;Linux源码编译安装1. 安装编译工具2. 下载源代码3. 解压源代码4. 配置5. 编译6. 测试&#xff08;可选&#xff09;7. 安装8. 清理&#xff08;可选&#xff09;9.注意事项 第二部分&#xff1a;链接命令硬链接&#xff08;Hard Link&#xf…...

科研绘图系列:R语言绘制线性回归连线图(line chart)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理画图保存图片系统信息参考介绍 科研绘图系列:R语言绘制线性回归连线图(line chart) 加载R包 library(tidyverse) library(ggthemes) libra…...

将ollama迁移到其他盘(eg:F盘)

文章目录 1.迁移ollama的安装目录2.修改环境变量3.验证 背景&#xff1a;在windows操作系统中进行操作 相关阅读 &#xff1a;本地部署deepseek模型步骤 1.迁移ollama的安装目录 因为ollama默认安装在C盘&#xff0c;所以只能安装好之后再进行手动迁移位置。 # 1.迁移Ollama可…...

Oracle 创建用户和表空间

Oracle 创建用户和表空间 使用sys 账户登录 建立临时表空间 --建立临时表空间 CREATE TEMPORARY TABLESPACE TEMP_POS --创建名为TEMP_POS的临时表空间 TEMPFILE /oracle/oradata/POS/TEMP_POS.DBF -- 临时文件 SIZE 50M -- 其初始大小为50M AUTOEXTEND ON -- 支持…...

cursor ide配置远程ssh qt c++开发环境过程记录

cursor是啥就不介绍了&#xff0c;好像是目前最好用的ai ide&#xff0c;下面主要是配置远程ssh连接linux机器进行qt5 c程序运行的配置过程记录。 一、c_cpp_properties.json 在项目根目录的.vscode目录里面新建c_cpp_properties.json文件&#xff0c;根据你的实际情况配置该文…...

yolov5错误更改与相关参数详解(train.py)

1.错误更改 main中相关参数 if __name__ __main__:parser argparse.ArgumentParser()parser.add_argument(--weights, typestr, default, helpinitial weights path)parser.add_argument(--cfg, typestr, defaultmodels/yolov5s.yaml, helpmodel.yaml path)parser.add_arg…...

Python设计模式 - 组合模式

定义 组合模式&#xff08;Composite Pattern&#xff09; 是一种结构型设计模式&#xff0c;主要意图是将对象组织成树形结构以表示"部分-整体"的层次结构。这种模式能够使客户端统一对待单个对象和组合对象&#xff0c;从而简化了客户端代码。 组合模式有透明组合…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

ArcPy扩展模块的使用(3)

管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如&#xff0c;可以更新、修复或替换图层数据源&#xff0c;修改图层的符号系统&#xff0c;甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...