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

CGAL5.4.1 边塌陷算法

目录

1、使用曲面网格的示例 

2、使用默认多面体的示例

3、使用丰富多面体的示例

主要对1、使用曲面网格的示例  进行深度研究


CGAL编译与安装CGAL安装到验证到深入_cgal测试代码-CSDN博客 

参考资料CGAL 5.4.5 - Triangulated Surface Mesh Simplification: User Manual

 meshlab下载打开off文件MeshLab


 

1、使用曲面网格的示例 

下面的例子说明了如何简化曲面网格。未指定的代价策略默认为 Lindstrom-Turk。

 预览源文件 cube-meshed.off

stop_ratio  0.1代表只有之前10%的边量

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h>
#include <chrono>
#include <fstream>
#include <iostream>
typedef CGAL::Simple_cartesian<double>               Kernel;
typedef Kernel::Point_3                              Point_3;
typedef CGAL::Surface_mesh<Point_3>                  Surface_mesh;
namespace SMS = CGAL::Surface_mesh_simplification;
int main(int argc, char** argv)
{Surface_mesh surface_mesh;const std::string filename =CGAL::data_file_path(R"(C:\chenqi\ThridParty\CGAL-5.4.3\data\meshes\cube-meshed.off)");std::ifstream is(filename);if (!is || !(is >> surface_mesh)){std::cerr << "Failed to read input mesh: " << filename << std::endl;return EXIT_FAILURE;}if (!CGAL::is_triangle_mesh(surface_mesh)){std::cerr << "Input geometry is not triangulated." << std::endl;return EXIT_FAILURE;}std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();// In this example, the simplification stops when the number of undirected edges// drops below 10% of the initial countdouble stop_ratio =  0.1;SMS::Count_ratio_stop_predicate<Surface_mesh> stop(stop_ratio);int r = SMS::edge_collapse(surface_mesh, stop);std::chrono::steady_clock::time_point end_time = std::chrono::steady_clock::now();std::cout << "\nFinished!\n" << r << " edges removed.\n" << surface_mesh.number_of_edges() << " final edges.\n";std::cout << "Time elapsed: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count() << "ms" << std::endl;CGAL::IO::write_polygon_mesh(R"(C:\chenqi\ThridParty\CGAL-5.4.3\data\meshes\out.off)", surface_mesh, CGAL::parameters::stream_precision(17));return EXIT_SUCCESS;
}

 

 

2、使用默认多面体的示例

下面的示例展示了使用默认顶点、半边和面简化多面体_3 的过程。未指定的代价策略默认为 Lindstrom-Turk。

C:\chenqi\ThridParty\CGAL-5.4.3\data\meshes\small_cube.off  1000    C:\chenqi\ThridParty\CGAL-5.4.3\data\meshes\small_cube_out.off
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
// Simplification function
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
// Stop-condition policy
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h>
#include <iostream>
#include <fstream>
typedef CGAL::Simple_cartesian<double>                      Kernel;
typedef CGAL::Polyhedron_3<Kernel>                          Surface_mesh;
namespace SMS = CGAL::Surface_mesh_simplification;
int main(int argc, char** argv)
{Surface_mesh surface_mesh;const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/small_cube.off");std::ifstream is(filename);if (!is || !(is >> surface_mesh)){std::cerr << "Failed to read input mesh: " << filename << std::endl;return EXIT_FAILURE;}if (!CGAL::is_triangle_mesh(surface_mesh)){std::cerr << "Input geometry is not triangulated." << std::endl;return EXIT_FAILURE;}// This is a stop predicate (defines when the algorithm terminates).// In this example, the simplification stops when the number of undirected edges// left in the surface mesh drops below the specified number (1000)const std::size_t edge_count_treshold = (argc > 2) ? std::stoi(argv[2]) : 1000;SMS::Count_stop_predicate<Surface_mesh> stop(edge_count_treshold);// This the actual call to the simplification algorithm.// The surface mesh and stop conditions are mandatory arguments.// The index maps are needed because the vertices and edges// of this surface mesh lack an "id()" field.std::cout << "Collapsing edges of Polyhedron: " << filename << ", aiming for " << edge_count_treshold << " final edges..." << std::endl;int r = SMS::edge_collapse(surface_mesh, stop,CGAL::parameters::vertex_index_map(get(CGAL::vertex_external_index, surface_mesh)).halfedge_index_map(get(CGAL::halfedge_external_index, surface_mesh)));std::cout << "\nFinished!\n" << r << " edges removed.\n"<< (surface_mesh.size_of_halfedges() / 2) << " final edges.\n";std::ofstream os(argc > 3 ? argv[3] : "out.off");os.precision(17);os << surface_mesh;return EXIT_SUCCESS;
}

点和面一样 

3、 使用丰富多面体的示例

下面的示例等同于上一个示例,但使用的是丰富多面体,其半边支持 id 字段,用于存储算法所需的边索引。

C:\chenqi\ThridParty\CGAL-5.4.3\data\meshes\small_cube.off   0.1   C:\chenqi\ThridParty\CGAL-5.4.3\data\meshes\small_cube_out.off
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
// Extended polyhedron items which include an id() field
#include <CGAL/Polyhedron_items_with_id_3.h>
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h>
#include <iostream>
#include <fstream>
typedef CGAL::Simple_cartesian<double>                              Kernel;
typedef Kernel::Point_3                                             Point;
// Setup an enriched polyhedron type which stores an id() field in the items
typedef CGAL::Polyhedron_3<Kernel, CGAL::Polyhedron_items_with_id_3> Surface_mesh;
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor        vertex_descriptor;
typedef boost::graph_traits<Surface_mesh>::halfedge_descriptor      halfedge_descriptor;
namespace SMS = CGAL::Surface_mesh_simplification;
int main(int argc, char** argv)
{Surface_mesh surface_mesh;const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/small_cube.off");std::ifstream is(filename);if (!is || !(is >> surface_mesh)){std::cerr << "Failed to read input mesh: " << filename << std::endl;return EXIT_FAILURE;}if (!CGAL::is_triangle_mesh(surface_mesh)){std::cerr << "Input geometry is not triangulated." << std::endl;return EXIT_FAILURE;}// The items in this polyhedron have an "id()" field// which the default index maps used in the algorithm// need to get the index of a vertex/edge.// However, the Polyhedron_3 class doesn't assign any value to// this id(), so we must do it here:int index = 0;for (halfedge_descriptor hd : halfedges(surface_mesh))hd->id() = index++;index = 0;for (vertex_descriptor vd : vertices(surface_mesh))vd->id() = index++;// In this example, the simplification stops when the number of undirected edges// drops below xx% of the initial countconst double ratio = (argc > 2) ? std::stod(argv[2]) : 0.1;SMS::Count_ratio_stop_predicate<Surface_mesh> stop(ratio);// The index maps are not explicitelty passed as in the previous// example because the surface mesh items have a proper id() field.// On the other hand, we pass here explicit cost and placement// function which differ from the default policies, ommited in// the previous example.std::cout << "Collapsing edges of mesh: " << filename << ", aiming for " << 100 * ratio << "% of the input edges..." << std::endl;int r = SMS::edge_collapse(surface_mesh, stop);std::cout << "\nFinished!\n" << r << " edges removed.\n"<< (surface_mesh.size_of_halfedges() / 2) << " final edges.\n";std::ofstream os((argc > 3) ? argv[3] : "out.off");os.precision(17);os << surface_mesh;return EXIT_SUCCESS;
}

主要对1、使用曲面网格的示例  进行深度研究

曲面网格简化是指在尽可能保留整体形状、体积和边界的前提下,减少曲面网格中使用的面的数量。它与细分相反。

本文介绍的算法可以使用一种称为 "边缘折叠 "的方法,简化任何具有任意数量连接组件、有或无边界(边界或孔)和手柄(任意种属)的定向 2-manifold曲面。粗略地说,这种方法包括用一个顶点迭代替换一条边,每次折叠删除 2 个三角形。

边的折叠优先级由用户提供的成本函数决定,替换顶点的坐标由另一个用户提供的放置函数决定。当满足用户提供的停止谓词(如达到所需的边数)时,算法终止。

这里实现的算法是通用的,因为它不要求曲面网格是特定类型的,而要求它是可变曲面图(MutableFaceGraph)和半边列表图(HalfedgeListGraph)概念的模型。我们给出了 Surface_mesh、Polyhedron_3 和 OpenMesh 的示例。

计算折叠成本和顶点位置的具体方法称为成本策略。用户可以选择不同的策略,以策略和相关参数的形式传递给算法。
当前版本的软件包提供了一组实现三种策略的策略:默认的 Lindstrom-Turk 策略、Garland-Heckbert 策略以及由边长成本和可选的中点放置(速度更快,但精度较低)组成的策略。
文献[4]、[5]中介绍的策略的主要特点是,简化后的曲面网格在每一步都不会与原始曲面网格(或前一步的曲面网格)进行比较,因此无需保留额外的信息,如原始曲面网格或局部变化的历史记录。因此被称为无记忆简化。
与 Lindstrom-Turk 策略一样,[2] 中提出的 Garland-Heckbert 策略不将生成的网格与原始网格进行比较,也不依赖于局部变化的历史。相反,它通过为每个顶点分配四元矩阵来编码与原始网格的近似距离。

关键函数

/*
surface_mesh : 要简化的曲面网格
stop_predicate : 表示何时必须完成简化的策略
vertex_index_map(vimap):赋予每个顶点唯一整数索引的属性映射
edge_index_map(eimap):赋予每条边唯一整数索引的属性图
edge_is_constrained_map(ebmap):指定一条边是否为受约束边的属性图
get_cost(cf):计算折叠成本的函数对象
get_placement(pf):计算剩余顶点位置的函数对象
filter(filter):用于拒绝下一条折叠边的候选对象的函数对象
visitor(vis) : 跟踪简化过程的函数对象
*/
int r = edge_collapse(surface_mesh, stop_predicate、
                      CGAL::parameters::vertex_index_map(vimap)
                                       .edge_index_map(eimap)
                                       .edge_is_border_map(ebmap)
                                       .get_cost(cf)
                                       .get_placement(pf)
                                       .filter(filter
                                       .visitor(vis)); 

这里读取的数据是off文件,如果需要读取其他文件例如ply,obj则需要转换位Surface_mesh格式,先解析一下这个格式

    Surface_mesh surface_mesh;const std::string filename = CGAL::data_file_path(R"(C:\chenqi\ThridParty\CGAL-5.4.3\data\meshes\bear.off)");std::ifstream is(filename);if (!is || !(is >> surface_mesh)){std::cerr << "Failed to read input mesh: " << filename << std::endl;return EXIT_FAILURE;}

  • 下载的obj网站:Borderlands角色扮演 | 免费3D模型 | 专业3D扫描方案 (artec3d.cn) 

读取obj进行网格简化,已经测试,这份代码只可以处理网格,不可以处理带纹理的


#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/IO/OBJ.h>
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h>
#include <fstream>typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Surface_Mesh;
namespace SMS = CGAL::Surface_mesh_simplification;int main() {Surface_Mesh surface_mesh;std::string input_filename = R"(C:\Users\Administrator\Desktop\OBJ\borderlands_cosplay-obj\out.obj)"; // Replace with your input OBJ file pathstd::string output_filename = R"(C:\Users\Administrator\Desktop\OBJ\borderlands_cosplay-obj\out2.obj)"; // Replace with your desired output OBJ file path// Read the mesh from OBJ fileif (!CGAL::IO::read_polygon_mesh(input_filename, surface_mesh)) {std::cerr << "Failed to read input mesh: " << input_filename << std::endl;return EXIT_FAILURE;}// Perform edge collapse simplificationdouble stop_ratio = 0.5; // Adjust this ratio as neededSMS::Count_ratio_stop_predicate<Surface_Mesh> stop(stop_ratio);SMS::edge_collapse(surface_mesh, stop);// Write the simplified mesh to OBJ fileif (!CGAL::IO::write_polygon_mesh(output_filename, surface_mesh)) {std::cerr << "Failed to write output mesh: " << output_filename << std::endl;return EXIT_FAILURE;}return EXIT_SUCCESS;
}

至于实现纹理贴图自动更新,需要自己额外实现塌陷策略、停止的标准。目前代码是已经有一部分了,还需要完善,后续会更新。

  1. 在简化前记录纹理坐标:在开始网格简化之前,记录下每个顶点的纹理坐标。

  2. 自定义边缘坍塌操作:实现一个自定义的边缘坍塌策略,在边缘坍塌的同时更新相关顶点的纹理坐标。这可能涉及计算坍塌操作中涉及的顶点的新纹理坐标。

  3. 简化网格:使用自定义策略来简化网格。

  4. 输出简化后的网格和纹理坐标:在简化过程完成后,输出简化后的网格和更新后的纹理坐标到 OBJ 文件。

参考文章:网格简化 QEM 方法详解 - 知乎 (zhihu.com) 

相关文章:

CGAL5.4.1 边塌陷算法

目录 1、使用曲面网格的示例 2、使用默认多面体的示例 3、使用丰富多面体的示例 主要对1、使用曲面网格的示例 进行深度研究 CGAL编译与安装CGAL安装到验证到深入_cgal测试代码-CSDN博客 参考资料CGAL 5.4.5 - Triangulated Surface Mesh Simplification: User Manual …...

网络安全知识和华为防火墙

网络安全 网络空间安全 ---Cyberspace 2003年美国提出的网络空间概念 ---一个由信息基础设施组成的互相依赖的网络。 我国官方文件定义&#xff1a;网络空间为继海、陆、空、天以外的第五大人类互动领域。 通信保密阶段 --- 计算机安全阶段 --- 信息系统安全 --- 网络空间安…...

Docker 搭建MySQL主从复制-读写分离

一. 介绍 MySQL主从复制是一种常用的数据库高可用性解决方案&#xff0c;通过在主数据库上记录的数据变更&#xff0c;同步到一个或多个从数据库&#xff0c;实现数据的冗余备份和读写分离。在Docker环境下搭建MySQL主从复制和读写分离&#xff0c;不仅方便管理&#xff0c;还…...

[linux] which和find有什么区别?

which 和 find 都是 Unix/Linux 系统中的命令&#xff0c;但它们的用途和工作方式有很大的不同。 which 命令&#xff1a;which 命令是用来查找并显示用户可以在当前环境下执行的命令的完整路径。这些命令通常位于 PATH 环境变量中指定的目录中。例如&#xff0c;which python …...

使用Neo4j做技术血缘管理

目录 一、neo4j介绍 二、windows安装启动neo4j 2.1下载neo4j 2.2 解压文件 2.3 启动neo4j 三、neo4j基础操作 3.1 创建结点和关系 3.2 查询 3.3 更改 3.4 删除 四、技术血缘Demo实现 4.1 构建节点对象 4.2 构建存储对象 4.3 创建有属性关联关系 4.4 最后是图结果…...

Unity-WebGL

问题&#xff1a;提示gzip压缩报错解决&#xff1a;关闭打包的地方压缩&#xff0c;如下图问题&#xff1a;窗口未全屏解决&#xff1a;使用百分比画布替换固定尺寸画布 参考&#xff1a;新版Unity打包Webgl端进行屏幕自适应_unity webgl分辨率自适应-CSDN博客问题&#xff1a;…...

腾讯云部署vue+node项目

文章目录 一、安装宝塔二、vue项目部署三、node项目部署 前言: 关于项目部署,一开始也是找了很多资料,费了点时间,所以记录一下。希望能对各位有所帮助。 一、安装宝塔 1.首先在控制台,进入云服务器的终端界面 2.输入命令和密码获取权限,并且安装宝塔界面 yum install -y w…...

HBase表结构

HBase是非关系型数据库&#xff0c;是高可靠性、高性能、面向列、可伸缩、实时读写的分布式数据库。 HBase使用场景 大规模数据存储&#xff1a;如日志记录、数据库备份等。实时数据访问&#xff1a;如实时搜索、实时分析等。高性能读写&#xff1a;如高并发、低延迟的读写操…...

本人面试积累面试题更新中

本人面试积累面试题 1.事务的隔离级别 答:2024年1月30日 1.读已提交-----读取其他事务已经提交的数据 2.读未提交-----读取其他事务还未提交的数据–可能出现脏读 3.可重复读-----同一个事务多次读取同一个数据,尽可能的保证数据的一致性但是可能出现幻读 4.串行读------确保每…...

[经典面试题]169. 多数元素

题目描述 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff1a;3…...

Wireshark网络协议分析 - TCP协议

在我的博客阅读本文 文章目录 1. 基础2. 实战2.1. 用Go写一个简单的TCP服务器与客户端2.2. Wireshark抓包分析2.3. 限制数据包的大小——MSS与MTU2.4. 保证TCP的有序传输——Seq&#xff0c;Len与Ack2.5. TCP头标志位——URG&#xff0c;ACK&#xff0c;PSH&#xff0c;RST&…...

3 款最好的电脑硬盘数据迁移软件

您将从本页了解 3 款最好的 SSD硬盘数据迁移软件&#xff0c;磁盘供应商提供的软件和可靠的第三方软件。仔细阅读本文并做出您的选择。 什么是数据迁移&#xff1f; 数据迁移是将数据移动到其他计算机或存储设备的过程。在日常工作活动中&#xff0c;常见的数据迁移有三种&…...

【Java之HTML】

HTML 概念 互联网的产生&#xff1a;w3c的成立&#xff0c; ​ 互联网最开始设计的目的&#xff1a;看论文 ---->浏览器&#xff0c;HTML ​ 网络三要素&#xff1a;HTML HTTP URL HTML描述论文的格式 HTTP标记这个论文在网络上怎么传输 URL:指示这个论文在互联网的哪…...

支付宝支付功能解析,从零到掌握,轻松享受便捷支付

目录 一、支付宝支付功能简介 1.1 支付宝支付的概念 1.2 支付宝支付的优势 1.3 支付宝支付的适用场景 二、支付宝支付的准备工作 三、支付宝支付的接入流程 四、支付宝支付的安全性 5.1 支付宝支付的安全机制 5.2 防范支付风险的措施 5.3 支付宝支付的安全技术保障 …...

MacOS安装反编译工具JD-GUI以及解决无法打开的问题

目录 一.下载地址 二.安装 三.问题 四.解决办法 1.显示包内容 2.找到Contents/MacOS/universalJavaApplicationStub.sh 3.修改sh文件 4.保存后再次打开即可 一.下载地址 Java Decompiler 二.安装 将下载下来的 jd-gui-osx-1.6.6.tar 解压&#xff0c;然后将 JD-GUI.a…...

SpringBoot将第三方的jar中的bean对象自动注入到ioc容器中

新建一个模块&#xff0c;做自动配置 config&#xff1a;需要准备两个类&#xff0c;一个自动配置类&#xff0c;一个配置类 CommonAutoConfig&#xff1a;此类用于做自动配置类它会去读取resoutces下的META-INF.spring下的org.springframework.boot.autoconfigure.AutoConfig…...

5.变量的解构赋值 - JS

什么是解构赋值 通过类似&#xff08;或相同&#xff09;的构型&#xff0c;将已知数据的元素/属性解构并提取出来&#xff0c;再赋值到相应变量&#xff0c;可以是新建的变量&#xff0c;也可以是已存在的变量/属性等&#xff1b;最常见的是数组和对象的解构赋值&#xff0c;…...

tableau添加形状

目录 1.效果&#xff1a;1.自带的形状&#xff1a;2.添加形状&#xff1a;小结&#xff1a; 1.效果&#xff1a; 1.自带的形状&#xff1a; 2.添加形状&#xff1a; 找到tableau的安装目录&#xff0c;点入 默认->形状 的文件夹&#xff1a; 新建一个文件夹&#xff1a; …...

(2)(2.10) LTM telemetry

文章目录 前言 1 协议概述 2 配置 3 带FPV视频发射器的使用示例 4 使用TCM3105的FSK调制解调器示例 前言 轻量级 TeleMetry 协议 (LTM) 是一种单向通信协议&#xff08;从飞行器下行的数据链路&#xff09;&#xff0c;可让你以低带宽/低波特率&#xff08;通常为 2400 波…...

工具推荐系列-极客编辑器(实时在线编写md文件同步GitHub)

工具项目地址&#xff1a;https://github.com/geekeditor/geekeditor-desktop-releases/tree/main 工具基础配置方法&#xff1a;https://www.geekeditor.com/workspace1.x.html 详细同步代码仓的方法可以用下面&#xff1a; 如何创建GitHub仓库 及生成获取AccessToken&#xf…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...