10、基于osg引擎生成热力图高度图实现3D热力图可视化、3D热力图实时更新(带过渡效果)
1、结果


2、完整C++代码
#include <sstream>
#include <iomanip>
#include <iostream>
#include <vector>
#include <random>
#include <cmath>
#include <functional>
#include <osgViewer/viewer>
#include <osgDB/ReadFile>
#include <osg/Texture3D>
#include <osg/Texture1D>
#include <osgDB/FileUtils>
#include <osg/Billboard>
#include <osg/TexGenNode>
#include <osg/ClipNode>
#include <osgDB/WriteFile>
#include <osg/Point>
#include <osg/ShapeDrawable>
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osgGA/TrackballManipulator>
#include <osg/ComputeBoundsVisitor>
#include <osg/TransferFunction>
#include <array>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/StateSetManipulator>
#include <osgUtil/SmoothingVisitor>
const std::string DATA_PATH = R"(..\data\)";
const std::string SHADER_PATH = R"(..\shaders\)";
const float RADIUS = 35;//设置热力点的影响半径
struct Point { int x, y; float value; };
// 生成随机数
int getRandomInt(int min, int max) {return min + std::rand() % (max - min + 1);
}// 颜色插值(用于热力图渐变)
osg::Vec4 lerpColor(float value) {value = osg::clampBetween(value, 0.0f, 1.0f); // 确保 value 在 [0, 1] 范围内osg::Vec4 colors[] = {osg::Vec4(49/255.0, 54/255.0, 149/255.0, value),osg::Vec4(69/255.0, 117/255.0, 180/255.0, value),osg::Vec4(116/255.0, 173/255.0, 209/255.0, value),osg::Vec4(171/255.0, 217/255.0, 233/255.0, value),osg::Vec4(224/255.0, 243/255.0, 248/255.0, value),osg::Vec4(255/255.0, 255/255.0, 191/255.0, value),osg::Vec4(254/255.0, 224/255.0, 144/255.0, value),osg::Vec4(253/255.0, 174/255.0, 97/255.0, value),osg::Vec4(244/255.0, 109/255.0, 67/255.0, value),osg::Vec4(215/255.0, 48/255.0, 39/255.0, value),osg::Vec4(165/255.0, 0.0, 38/255.0, value)};//osg::Vec4 colors[] = {// osg::Vec4(50 / 255.0, 136 / 255.0, 189 / 255.0, value), // osg::Vec4(102 / 255.0, 194 / 255.0, 165 / 255.0, value),// osg::Vec4(171 / 255.0, 221 / 255.0, 164 / 255.0, value),// osg::Vec4(230 / 255.0, 245 / 255.0, 152 / 255.0, value),// osg::Vec4(254 / 255.0, 224 / 255.0, 139 / 255.0, value),// osg::Vec4(253 / 255.0, 174 / 255.0, 97 / 255.0, value),// osg::Vec4(244 / 255.0, 109 / 255.0, 67 / 255.0, value),// osg::Vec4(213 / 255.0, 62 / 255.0, 79 / 255.0, value),//};int numColors = sizeof(colors) / sizeof(colors[0]);float t = value * (numColors - 1); // 乘以 (数量-1)int index = static_cast<int>(t);// 处理边界情况,避免越界if (index >= numColors - 1) {return colors[numColors - 1]; // 直接返回最后一个颜色}t -= index;// 提取 t 的小数部分,作为插值比例return colors[index] * (1 - t) + colors[index + 1] * t;
}std::vector<Point> generateData(int width, int height, int pointCount)
{std::vector<Point> points;for (int i = 0; i < pointCount; ++i) {points.push_back({ getRandomInt(10, width - 10), getRandomInt(10, height - 10), getRandomInt(0, 100) / 100.0f });}return points;
}// 生成热力图图像
osg::ref_ptr<osg::Image> generateHeatmap(int width, int height, std::vector<Point> points) {osg::ref_ptr<osg::Image> image = new osg::Image();image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);std::vector<unsigned char> buffer(width * height * 4, 0); // 初始化RGBA缓冲区// 绘制点 (模拟圆形模糊)for (const auto& p : points) {for (int dx = -RADIUS; dx <= RADIUS; ++dx) {for (int dy = -RADIUS; dy <= RADIUS; ++dy) {int px = p.x + dx;//计算当前像素的x坐标int py = p.y + dy;//计算当前像素的y坐标//确保当前像素点在图像范围内if (px >= 0 && px < width && py >= 0 && py < height) {//计算该像素点与中心点的归一化距离float dist = std::sqrt(dx * dx + dy * dy) / RADIUS;//如果距离在热力点影响范围内if (dist <= 1.0f) {//计算当前像素在缓冲区中的索引int index = (py * width + px) * 4;//计算当前像素的影响强度float intensity = (1.0f - dist) * p.value;//叠加透明度float oldAlpha = buffer[index + 3] / 255.0f; // 读取背景透明度(归一化到0~1)float newAlpha = intensity + oldAlpha * (1.0f - intensity); // 计算混合透明度buffer[index + 3] = static_cast<int>(std::min(255.0f, newAlpha * 255)); // 更新透明度}}}}}// 颜色映射for (int i = 0; i < width * height; ++i) {float alpha = buffer[i * 4 + 3] / 255.0f; // 归一化透明度osg::Vec4 color = lerpColor(alpha);buffer[i * 4] = static_cast<unsigned char>(color.r() * 255);buffer[i * 4 + 1] = static_cast<unsigned char>(color.g() * 255);buffer[i * 4 + 2] = static_cast<unsigned char>(color.b() * 255);buffer[i * 4 + 3] = static_cast<unsigned char>(color.a() * 255);}// 复制数据到 osg::Imagememcpy(image->data(), buffer.data(), buffer.size());return image;
}// 生成高度图
osg::ref_ptr<osg::Image> generateHeightmap(int width, int height, std::vector<Point> points)
{osg::ref_ptr<osg::Image> image = new osg::Image;image->allocateImage(width, height, 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);std::vector<float> heightBuffer(width * height, 0.0);//浮点型高度缓存// 计算高度影响(使用高斯衰减)for (const auto& p : points){for (int dx = -RADIUS; dx <= RADIUS; ++dx) {for (int dy = -RADIUS; dy <= RADIUS; ++dy) {int px = p.x + dx;int py = p.y + dy;if (px >= 0 && px < width && py >= 0 && py < height){float distance = std::sqrt(dx * dx + dy * dy);if (distance <= RADIUS) {float normalizedDist = distance / RADIUS;//高斯衰减系数float falloff = std::exp(-normalizedDist * normalizedDist * 4.0f);int index = py * width + px;heightBuffer[index] += falloff * p.value;}}}}}// 归一化处理float maxHeight = *std::max_element(heightBuffer.begin(), heightBuffer.end());std::vector<unsigned char> grayBuffer(width * height);for (int i = 0; i < width * height; ++i){float normalized = heightBuffer[i] / maxHeight;grayBuffer[i] = static_cast<unsigned char>(normalized * 255);}memcpy(image->data(), grayBuffer.data(), grayBuffer.size());return image;
}void generateHeatmapTexture()
{std::vector<Point> data = generateData(1024, 1024, 100);osg::ref_ptr<osg::Image> heatmap2dImage = generateHeatmap(1024, 1024, data);osg::ref_ptr<osg::Image> heightmapImage = generateHeightmap(1024, 1024, data);// 使用OSG保存图像if (osgDB::writeImageFile(*heatmap2dImage, "heatmap2d.png")) {std::cout << "Image saved as " << "heatmap_osg.png" << std::endl;}else {std::cerr << "Error saving image." << std::endl;}if (osgDB::writeImageFile(*heightmapImage, "heightmap.png")) {std::cout << "Image saved as " << "heightmap.png" << std::endl;}else {std::cerr << "Error saving image." << std::endl;}
}// 创建地形节点
osg::ref_ptr<osg::Node> createTerrain(osg::Image* heightmap, osg::Image* heatmap) {// 创建几何体osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();osg::ref_ptr<osg::Geode> geode = new osg::Geode();geode->addDrawable(geometry);// 创建顶点数组osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();const int width = heightmap->s();const int height = heightmap->t();const float terrainSize = 200.0f; // 地形物理尺寸const float heightScale = 50.0f; // 高度缩放系数// 生成顶点数据unsigned char* heightData = heightmap->data();for (int y = 0; y < height; ++y) {for (int x = 0; x < width; ++x) {// 计算顶点位置(居中)float xPos = (x - width / 2.0f) * (terrainSize / width);float yPos = (y - height / 2.0f) * (terrainSize / height);float zPos = heightData[y * width + x] / 255.0f * heightScale;vertices->push_back(osg::Vec3(xPos, yPos, zPos));}}// 创建索引数组(三角形带)osg::ref_ptr<osg::DrawElementsUShort> indices =new osg::DrawElementsUShort(GL_TRIANGLES);for (int y = 0; y < height - 1; ++y) {for (int x = 0; x < width - 1; ++x) {// 创建两个三角形组成四边形int i0 = y * width + x;int i1 = i0 + 1;int i2 = i0 + width;int i3 = i2 + 1;indices->push_back(i1);indices->push_back(i2);indices->push_back(i0);indices->push_back(i3);indices->push_back(i2);indices->push_back(i1);}}// 设置几何体数据geometry->setVertexArray(vertices);geometry->addPrimitiveSet(indices);// 自动生成法线osgUtil::SmoothingVisitor::smooth(*geometry);// 创建纹理坐标数组osg::ref_ptr<osg::Vec2Array> texCoords = new osg::Vec2Array();for (int y = 0; y < height; ++y) {for (int x = 0; x < width; ++x) {// 归一化纹理坐标 [0,1]float u = static_cast<float>(x) / (width - 1);float v = static_cast<float>(y) / (height - 1);texCoords->push_back(osg::Vec2(u, v));}}geometry->setTexCoordArray(0, texCoords);// 应用纹理osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();texture->setImage(heatmap);texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);osg::StateSet* stateset = geode->getOrCreateStateSet();stateset->setTextureAttributeAndModes(0, texture);stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);stateset->setMode(GL_BLEND, osg::StateAttribute::ON);return geode;
}osg::Geode* createHeatmap3D() {const int GRID_SIZE = 256;osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;osg::ref_ptr<osg::Vec2Array> texCoords = new osg::Vec2Array;for (int y = 0; y < GRID_SIZE; ++y) {for (int x = 0; x < GRID_SIZE; ++x) {float u = x / (GRID_SIZE - 1.0f);float v = y / (GRID_SIZE - 1.0f);vertices->push_back(osg::Vec3(u * 100 - 50, v * 100 - 50, 0)); // 居中显示texCoords->push_back(osg::Vec2(u, v));}}// 创建索引osg::ref_ptr<osg::DrawElementsUInt> indices =new osg::DrawElementsUInt(GL_TRIANGLES);for (int y = 0; y < GRID_SIZE - 1; ++y) {for (int x = 0; x < GRID_SIZE - 1; ++x) {int i0 = y * GRID_SIZE + x;int i1 = i0 + 1;int i2 = i0 + GRID_SIZE;int i3 = i2 + 1;indices->push_back(i1);indices->push_back(i2);indices->push_back(i0);indices->push_back(i3);indices->push_back(i2);indices->push_back(i1);}}geom->setVertexArray(vertices);geom->setTexCoordArray(0, texCoords);geom->addPrimitiveSet(indices);osgUtil::SmoothingVisitor::smooth(*geom);osg::Geode* geode = new osg::Geode;geode->addDrawable(geom);return geode;
}osg::Texture2D* createTexture(osg::Image* image) {osg::Texture2D* tex = new osg::Texture2D;tex->setImage(image);tex->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);tex->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);tex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);tex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);return tex;
}void setupStateSet(osg::Geode* geode) {osg::StateSet* ss = geode->getOrCreateStateSet();// 混合设置ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);ss->setMode(GL_BLEND, osg::StateAttribute::ON);std::vector<Point> data = generateData(256, 256, 100);osg::ref_ptr<osg::Image> heatmap2dImage1 = generateHeatmap(256, 256, data);osg::ref_ptr<osg::Image> heightmapImage1 = generateHeightmap(256, 256, data);struct Textures {osg::ref_ptr<osg::Texture2D> current;osg::ref_ptr<osg::Texture2D> next;float transition = 0.0f;bool updating = false;};Textures heightTex, heatmapTex;// 初始纹理heightTex.current = createTexture(heightmapImage1);heatmapTex.current = createTexture(heatmap2dImage1);data = generateData(256, 256, 200);osg::ref_ptr<osg::Image> heatmap2dImage2 = generateHeatmap(256, 256, data);osg::ref_ptr<osg::Image> heightmapImage2 = generateHeightmap(256, 256, data);heightTex.next = createTexture(heightmapImage2);heatmapTex.next = createTexture(heatmap2dImage2);osg::Program* program = new osg::Program;ss->setAttribute(program);program->addShader(osgDB::readRefShaderFile(osg::Shader::VERTEX, SHADER_PATH + R"(heatmap3d.vert)"));program->addShader(osgDB::readRefShaderFile(osg::Shader::FRAGMENT, SHADER_PATH + R"(heatmap3d.frag)"));ss->setAttributeAndModes(program);program->addBindAttribLocation("texCoord", osg::Drawable::TEXTURE_COORDS_0);// 绑定纹理单元ss->setTextureAttribute(0, heightTex.current);ss->setTextureAttribute(1, heightTex.next);ss->setTextureAttribute(2, heatmapTex.current);ss->setTextureAttribute(3, heatmapTex.next);// Uniform绑定ss->addUniform(new osg::Uniform("heightMap", 0));ss->addUniform(new osg::Uniform("nextHeightMap", 1));ss->addUniform(new osg::Uniform("heatmap", 2));ss->addUniform(new osg::Uniform("nextHeatmap", 3));ss->addUniform(new osg::Uniform("transitionProgress", 0.0f));
}osg::Timer_t startTime;
bool startSimulate = false;
class KeyboardEventHandler : public osgGA::GUIEventHandler {
public:KeyboardEventHandler(){}bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override {if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) {switch (ea.getKey()) {case 't': if (!startSimulate){startTime = osg::Timer::instance()->tick();startSimulate = true;}return true;default:return false;}}return false;}private:
};class TimeUpdateCallback : public osg::NodeCallback
{
public:TimeUpdateCallback() {}virtual void operator()(osg::Node* node, osg::NodeVisitor* nv){if (startSimulate){osg::StateSet* ss = node->getStateSet();if (ss){float time = osg::Timer::instance()->delta_s(startTime, osg::Timer::instance()->tick()) / 3.0f;time = osg::clampBetween(time, 0.0f, 1.0f);if (time == 1.0){std::random_device rd; // 用于获取随机种子std::mt19937 gen(rd()); // 使用 Mersenne Twister 算法// 定义一个分布范围 [100, 200]std::uniform_int_distribution<> dis(100, 200);std::vector<Point> data = generateData(256, 256, dis(gen));osg::ref_ptr<osg::Image> heatmap2dImage = generateHeatmap(256, 256, data);osg::ref_ptr<osg::Image> heightmapImage = generateHeightmap(256, 256, data);ss->setTextureAttribute(0, ss->getTextureAttribute(1, osg::StateAttribute::TEXTURE));ss->setTextureAttribute(1, createTexture(heightmapImage));ss->setTextureAttribute(2, ss->getTextureAttribute(3, osg::StateAttribute::TEXTURE));ss->setTextureAttribute(3, createTexture(heatmap2dImage));ss->getUniform("transitionProgress")->set(0.0f);startTime = osg::Timer::instance()->tick();}elsess->getUniform("transitionProgress")->set(time);}traverse(node, nv);}}};int preview3DHeatmapWithAnimate()
{osg::Geode* geode = createHeatmap3D();setupStateSet(geode);geode->setUpdateCallback(new TimeUpdateCallback());osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;osg::ref_ptr<osg::Group> group = new osg::Group;group->addChild(geode);viewer->setSceneData(group);viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));viewer->addEventHandler(new osgViewer::StatsHandler());osg::ref_ptr<KeyboardEventHandler> keyboardHandler = new KeyboardEventHandler;viewer->addEventHandler(keyboardHandler);return viewer->run();
}int preview3DHeatmap()
{std::vector<Point> data = generateData(256, 256, 100);osg::ref_ptr<osg::Image> heatmap2dImage = generateHeatmap(256, 256, data);osg::ref_ptr<osg::Image> heightmapImage = generateHeightmap(256, 256, data);osg::ref_ptr<osg::Node> node = createTerrain(heightmapImage, heatmap2dImage);osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;osg::ref_ptr<osg::Group> group = new osg::Group;group->addChild(node);viewer->setSceneData(group);viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));viewer->addEventHandler(new osgViewer::StatsHandler());return viewer->run();
}int preview2DHeatmap() {std::vector<Point> data = generateData(256, 256, 100);osg::ref_ptr<osg::Image> heatmap2dImage = generateHeatmap(256, 256, data);// 创建带纹理的四边形几何体osg::ref_ptr<osg::Geometry> quad = osg::createTexturedQuadGeometry(osg::Vec3(-1.0f, -1.0f, 0.0f), // 左下角顶点osg::Vec3(2.0f, 0.0f, 0.0f), // 宽度向量osg::Vec3(0.0f, 2.0f, 0.0f), // 高度向量0.0f, 0.0f, 1.0f, 1.0f // 纹理坐标 (左下角到右上角));osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;texture->setImage(heatmap2dImage);osg::ref_ptr<osg::StateSet> stateSet = quad->getOrCreateStateSet();stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);// 创建Geode并添加几何体osg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable(quad);// 创建场景图根节点osg::ref_ptr<osg::Group> root = new osg::Group;root->addChild(geode);// 创建并设置ViewerosgViewer::Viewer viewer;viewer.setSceneData(root);return viewer.run();
}int main()
{//return preview2DHeatmap();//return preview3DHeatmap();return preview3DHeatmapWithAnimate();
}
3、着色器代码
//heatmap3d.vert
#version 110
/* GLSL 1.10需要显式声明精度 (OpenGL ES要求) */
#ifdef GL_ES
precision highp float;
#endif
/* 自定义 uniforms */
uniform sampler2D heightMap;
uniform sampler2D nextHeightMap;
uniform float transitionProgress;
attribute vec2 texCoord;
// 输入纹理坐标属性(对应几何体的第0层纹理)
varying vec2 vTexCoord;void main() {float x = gl_Vertex.x;float y = gl_Vertex.y;vTexCoord = texCoord;// 使用 texture2D 代替 texture 函数float currentHeight = texture2D(heightMap, texCoord.xy).r * 50.0;float nextHeight = texture2D(nextHeightMap, texCoord.xy).r * 50.0;// 高度插值计算float finalHeight = mix(currentHeight, nextHeight, transitionProgress);// 坐标变换vec4 pos = vec4(x, y, finalHeight, 1.0);gl_Position = gl_ModelViewProjectionMatrix * pos;
}
//heatmap3d.frag
#version 110
/* GLSL 1.10需要显式声明精度 (OpenGL ES要求) */
#ifdef GL_ES
precision mediump float;
#endifuniform sampler2D heatmap;
uniform sampler2D nextHeatmap;
uniform float transitionProgress;
varying vec2 vTexCoord;void main() {// 使用texture2D替代texture函数vec4 currentColor = texture2D(heatmap, vTexCoord);vec4 nextColor = texture2D(nextHeatmap, vTexCoord);// 使用gl_FragColor替代自定义输出gl_FragColor = mix(currentColor, nextColor, transitionProgress);
}相关文章:
10、基于osg引擎生成热力图高度图实现3D热力图可视化、3D热力图实时更新(带过渡效果)
1、结果 2、完整C代码 #include <sstream> #include <iomanip> #include <iostream> #include <vector> #include <random> #include <cmath> #include <functional> #include <osgViewer/viewer> #include <osgDB/Read…...
手搓智能音箱——语音识别及调用大模型回应
一、代码概述 此 Python 代码实现了一个语音交互系统,主要功能为监听唤醒词,在唤醒后接收用户语音问题,利用百度语音识别将语音转换为文本,再调用 DeepSeek API 获取智能回复,最后使用文本转语音功能将回复朗读出来。 …...
Modbus通信协议基础知识总结
1. 数据类型与存储区分类 Modbus协议将数据分为四类存储区,通过存储区代号区分: 输出线圈(0x):可读写,对应二进制开关量(如继电器状态),地址范围000001-065536ÿ…...
vue3 + css 列表无限循环滚动+鼠标移入停止滚动+移出继续滚动
1.动画文件.vue <template><div class"dashboard" click"setFullScreen"><div class"warp-box"><el-scrollbar ref"scrollRef" height"100%" scroll"handelScroll"><div class"…...
使用 CryptoJS 实现 AES 解密:动态数据解密示例
在现代加密应用中,AES(高级加密标准)是一种广泛使用的对称加密算法。它的安全性高、效率好,适合用于各种加密任务。今天,我们将通过一个实际的示例,展示如何使用 CryptoJS 实现 AES 解密,解密动态数据。CryptoJS 是一个基于 JavaScript 的加密库,它支持 AES、DES 等多种…...
Go语言对于MySQL的基本操作
一.下载依赖 终端中输入: go get -u github.com/go-sql-driver/mysql 导入包 import ("database/sql"_ "github.com/go-sql-driver/mysql" ) 二.案例 package main//go get-u github.com/go-sql-driver/mysql 获取驱动 import ("databa…...
AndroidStudio下载安装,环境部署以及常见问题解决教程(亲测)
AndroidStudio下载安装,环境部署以及常见问题解决!!! 文章目录 前言 一、Android Studio 下载与安装 1.1 系统要求 1.2 下载 Android Studio 1.3 安装 Android Studio Windows 系统 1.4 初始配置 二、环境部署 2.1 安装 …...
开源免费一句话生成儿童故事视频核心思想解析
再看一个演示视频,学会核心思想后,可以打造自己的内容生成工具,后文有基于飞书多维表格的实现效果: 一句话灵感生成儿童故事视频演示 这是一款专门为内容素材创作打造的创新工具,可根据用户输入的主题,快速…...
数据结构——最短路(BFS,Dijkstra,Floyd)
完整版可以看我的最短路问题模版总结_稠密图最短路-CSDN博客 考研数据结构只考BFS,Dijkstra和Floyd 下面代码以Acwing模板题为例 BFS代码 适用类型: 1.单源最短路径 2.无权图 3.不适用于带权图和负权回路图 //Acwing走迷宫bfs #include<bits/stdc.h>usi…...
Kali Linux汉化教程:轻松设置中文界面
1.打开终端 2.输入sudo dpkg-reconfigure locales,回车,输入密码,回车 sudo dpkg-reconfigure locales 3.往下滑,滑到底,找到‘zh_CN.UTF-8 UTF-8’,回车 4.选择‘zh_CN.UTF-8’,回车 5.没有 ‘zh_CN.UTF-8’选项的特…...
分布式锁: 并发时,redis如何避免删别人的锁
在使用Redis实现分布式锁的时候,如何避免在并发情况下误删别人的锁。首先,分布式锁的基本概念:是多个客户端在访问共享资源时,通过某种机制来确保同一时间只有一个客户端能持有锁。 Redis通常用SET命令加上NX选项来创建锁…...
Leetcode 160 Intersection of Two Linked Lists
题意 给定两个链表,找这两个链表第一个公共节点,如果没有返回nullptr 题目链接 https://leetcode.com/problems/intersection-of-two-linked-lists/description/ 题解 两个指针分别从两个链表(记录为表A,表B)的表…...
【八股文】从浏览器输入一个url到服务器的流程
1.url解析与DNS解析 浏览器解析用户输入的URL,提取协议(HTTP\HTTPS)、域名、端口及路径等信息 浏览器首先检查本地DNS缓存和系统DNS缓存,若未命中,查询本地hosts文件 最后递归查询向本地DNS服务器发起请求ÿ…...
C++和标准库速成(八)——指针、动态数组、const、constexpr和consteval
目录 1. 指针和动态数组1.1 栈和自由存储区1.2 使用指针1.3 动态分配的数组1.4 空指针常量 2. const2.1 const修饰类型2.2 const与指针2.3 使用const保护参数2.4 const方法(建议) 3. constexpr4. consteval参考 1. 指针和动态数组 动态内存允许所创建的程序具有在编…...
超声重建,3D重建 超声三维重建,三维可视化平台 UR 3D Reconstruction
1. 超声波3D重建技术的实现方法与算法 技术概述 3D超声重建是一种基于2D超声图像生成3D体积数据的技术,广泛应用于医学影像领域。通过重建和可视化三维结构,3D超声能够显著提高诊断精度和效率,同时减少医生的脑力负担。本技术文档将详细阐述…...
[HelloCTF]PHPinclude-labs超详细WP-Level 6Level 7Level 8Level 9-php://协议
由于Level 6-9 关的原理都是通用的, 这里就拿第6关举例, 其他的关卡同理 源码分析 定位到代码 isset($_GET[wrappers]) ? include("php://".$_GET[wrappers]) : ; 与前几关发生变化的就是 php:// 解题分析 这一关要求我们使用 php协议 php:// 协议 php://filte…...
【Linux】Bash是什么?怎么使用?
李升伟 整理 什么是 Bash? Bash(Bourne Again Shell)是一种 命令行解释器(Shell),广泛用于 Unix 和 Linux 操作系统。它是 Bourne Shell(sh) 的增强版,提供了更多的功能…...
cmake结合qt开发界面程序实例
在使用 CMake 构建 Qt 界面应用程序时,你需要设置 CMakeLists.txt 文件来指定项目配置、源文件、库依赖等。以下是一个简单的示例,展示了如何创建一个包含 Qt 界面(使用 QWidget)的 Qt 项目,并使用 CMake 进行构建。 …...
vue3二次封装tooltip实现el-table中的show-overflow-tooltip效果
开发过程中遇到需要根据后端返回的数据长度来判断是否需要使用el-tooltip的情况,想到el-table里面就有这种交互效果,如果不论文字是否超出容器长度都展示tooltip的话,交互效果难免会差很多,所以二次封装了这个组件: 给…...
如何创建并保存HTML文件?零基础入门教程
原文:如何创建并保存HTML文件?零基础入门教程 | w3cschool笔记 本文将以Windows系统为例,教你用最简单的记事本创建并保存第一个HTML网页。 📝 第一步:准备工具 文本编辑器:使用系统自带的记事本ÿ…...
React19源码系列之FiberRoot节点和Fiber节点
在上一篇文章,看了createRoot函数的大致流程。 createContainer函数创建并返回了FiberRoot 。FiberRoot是由createFiberRoot函数创建, createFiberRoot函数还将 FiberRoot和 根Fiber 通过current属性建立起了联系。将FiberRoot作为参数传给 ReactDOMRoo…...
每天看一篇漏洞报告
前言: 内容来源于乌云漏洞 今日思考xss漏洞, 今天看到一篇文章,里面详细说了xss的绕过技巧,虽然时间久了,没有去尝试,待会有时间去测试一下 以下是整理后的文章,原文在下面 文章链接&#…...
采用贝塞尔函数,进行恒定束宽波束形成算法
matlab采用贝塞尔函数,进行恒定束宽波束形成算法 beselle.m , 1452 20191225160928.png , 43700 20191225160935.png , 45238 20191225161010.png , 76862...
TCP协议的多线程应用、多线程下的网络编程
DAY13.2 Java核心基础 多线程下的网络编程 基于单点连接的方式,一个服务端对应一个客户端,实际运行环境中是一个服务端需要对应多个客户端 创建ServerSocketNable类,多线程接收socket对象 public class ServerSocketNable implements Run…...
华为中小型企业项目案例
实验目的(1) 熟悉华为交换机和路由器的应用场景 (2) 掌握华为交换机和路由器的配置方法 实验拓扑实验拓扑如图所示。 华为中小型企业项目案例拓扑图 实验配置市场部和技术部的配置创建VLANLSW1的配置 [LSW1]vlan batch 10 20 [LSW1]q…...
LabVIEW VI Scripting随机数波形图自动生成
通过LabVIEW VI Scripting 技术,实现从零开始编程化创建并运行一个随机数波形监测VI。核心功能包括自动化生成VI框架、添加控件与函数、配置数据流逻辑及界面布局优化,适用于批量生成测试工具、教学模板开发或复杂系统的模块化构建。通过脚本化操作&…...
MATLAB 控制系统设计与仿真 - 26
状态空间控制系统概述 状态空间描述 现代控制理论是建立在状态空间基础上的控制系统分析和设计理论,它用状态变量来刻画系统的内部特征,用‘一节微分方程组’来描述系统的动态特性。系统的状态空间模型描述了系统输入/输出与内部状态之间的关系&#x…...
Python----计算机视觉处理(Opencv:图像镜像旋转)
一、图像镜像旋转 图像的旋转是围绕一个特定点进行的,而图像的镜像旋转则是围绕坐标轴进行的。图像镜像旋转,也可 以叫做图像翻转,分为水平翻转、垂直翻转、水平垂直翻转三种。 通俗的理解为,当以图片的中垂线为x轴和y轴时&#x…...
C++从入门到入土(八)——多态的原理
目录 前言 多态的原理 动态绑定与静态绑定 虚函数表 小结 前言 在前面的文章中,我们介绍了C三大特性之一的多态,我们主要介绍了多态的构成条件,但是对于多态的原理我们探讨的是不够深入的,下面这这一篇文章,我们将…...
国产编辑器EverEdit - 语法着色文件的语法
1 语法着色定义(官方文档) 1.1 概述 EverEdit有着优异的语法着色引擎,可以高亮现存的绝大多数的编程语言。在EverEdit的语法着色中有Region和Item两个概念,Region表示着不同的区块。而Item则代表着这些区块中不同的部分。一般情况下,Region…...
