three.js实现3d球体树状结构布局——树状结构的实现
目录
- 系列文章
- 安装依赖
- 基本分析
- 实体类
- 场景
- 相机
- 渲染器
- 辅助线
- 环境光
- 点光源
- 球形几何体
- 球形几何体的材质
- 线几何体
- 线几何体的材质
- 物体
- 文本
- 轨道控制
- 实现效果
- 实现源码
- 参考文档
系列文章
three.js实现3d球体树状结构布局——添加入场、出场、点击放大等动画
安装依赖
npm i three three-spritetext three.meshline
three-spritetext: 用来绘制文字。THREE.TextGeometry绘制文字存在模糊问题,而且转动camera时three-spritetext不需要手动处理让文字始终面向camera。
three.meshline: 用来绘制线。THREE.LineBasicMaterial绘制线存在linewidth无效问题。
下面是此次案例版本
"three": "^0.150.1"
"three-spritetext": "^1.8.0"
"three.meshline": "^1.4.0"
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import SpriteText from 'three-spritetext';
import { MeshLine, MeshLineMaterial } from 'three.meshline'
基本分析
如题three.js实现3d球体树状结构布局是我们此次案例要实现的目标,那我们需要的实体有球、线、文本,以及场景、相机、渲染器、辅助线、灯光等实体。下面我们按照实体一步步来实现。
实体类
场景
const createScene = () => {return new THREE.Scene();
}
相机
本例以透视投影相机PerspectiveCamera为例
const createPerspectiveCamera = ({ fov, aspect, near, far }) => {// fov — 摄像机视锥体垂直视野角度// aspect — 摄像机视锥体长宽比// near — 摄像机视锥体近端面// far — 摄像机视锥体远端面return new THREE.PerspectiveCamera(fov, aspect, near, far);
}
渲染器
const createWebGLRenderer = ({ dom, width, height }) => {// renderDom — dom// width — 渲染宽度 一般取domclientWidth// height — 渲染高度 一般取clientHeightif (width === undefined) {width = dom.clientWidth;}if (height === undefined) {height = dom.clientHeight;}const renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);dom.appendChild(renderer.domElement);return renderer;
}
辅助线
const createAxesHelper = (length) => {return new THREE.AxesHelper(length)
}
环境光
const createAmbientLight = ({ color, intensity }) => {// color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。// intensity - (可选参数) 光照强度。 缺省值 1。return new THREE.AmbientLight(color, intensity);
}
点光源
// 环境光
const createPointLight = ({ color, intensity, distance, decay }) => {// color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。// intensity - (可选参数) 光照强度。 缺省值 1。// distance - 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.// decay - 沿着光照距离的衰退量。缺省值 2。return new THREE.PointLight(color, intensity, distance, decay);
}
球形几何体
const createSphereGeometry = ({radius,widthSegments,heightSegments,phiStart,phiLength,thetaStart,thetaLength
}) => {/*radius — 球体半径,默认为1。widthSegments — 水平分段数(沿着经线分段),最小值为3,默认值为32。heightSegments — 垂直分段数(沿着纬线分段),最小值为2,默认值为16。phiStart — 指定水平(经线)起始角度,默认值为0。。phiLength — 指定水平(经线)扫描角度的大小,默认值为 Math.PI * 2。thetaStart — 指定垂直(纬线)起始角度,默认值为0。thetaLength — 指定垂直(纬线)扫描角度大小,默认值为 Math.PI。*/return new THREE.SphereGeometry(radius,widthSegments,heightSegments,phiStart,phiLength,thetaStart,thetaLength);
}
球形几何体的材质
当然也可使用其他材质,本例使用MeshLambertMaterial
const createMeshLambertMaterial = (data) => {return new THREE.MeshLambertMaterial(data);
}
线几何体
const createLineGeometry = (points) => {const pointsVector3 = [];for (let i = 0; i < points.length; i++) {pointsVector3.push(new THREE.Vector3(points[i].x, points[i].y, points[i].z));}const geometry = new THREE.BufferGeometry().setFromPoints(pointsVector3);const line = new MeshLine();line.setGeometry(geometry);return line
}
线几何体的材质
const createMeshLineMaterial = (data) => {return new MeshLineMaterial({lineWidth: data.linewidth,color: data.color || "white",dashArray: data.dashArray || 0,transparent: true,})
}
物体
const createMesh = (geometry, materialBasic) => {return new THREE.Mesh(geometry, materialBasic);
}
文本
const createText = ({text, size, color}) => {let textClass = new SpriteText(text, size);textClass.color = color;return textClass
}
轨道控制
const createControl = (camera, dom) => {return new OrbitControls(camera, dom);
}
实现效果
实现源码
本案例以vue3编写
<script setup>
import { onMounted, ref, onBeforeUnmount, computed, reactive } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import SpriteText from "three-spritetext";
import { MeshLine, MeshLineMaterial } from "three.meshline";// 渲染dom
let treeDom = ref(null);
// 场景
const createScene = () => {return new THREE.Scene();
};
// 相机(透视投影相机)
const createPerspectiveCamera = ({ fov, aspect, near, far }) => {/* fov — 摄像机视锥体垂直视野角度aspect — 摄像机视锥体长宽比near — 摄像机视锥体近端面far — 摄像机视锥体远端面*/return new THREE.PerspectiveCamera(fov, aspect, near, far);
};
// 渲染器
const createWebGLRenderer = ({ dom, width, height }) => {/* renderDom — domwidth — 渲染宽度 一般取domclientWidthheight — 渲染高度 一般取clientHeight*/if (width === undefined) {width = dom.clientWidth;}if (height === undefined) {height = dom.clientHeight;}const renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);dom.appendChild(renderer.domElement);return renderer;
};
// 辅助线
const createAxesHelper = (length) => {return new THREE.AxesHelper(length);
};
// 环境光
const createAmbientLight = ({ color, intensity }) => {// color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。// intensity - (可选参数) 光照强度。 缺省值 1。return new THREE.AmbientLight(color, intensity);
};
// 点光
const createPointLight = ({ color, intensity, distance, decay }) => {/*color - (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。intensity - (可选参数) 光照强度。 缺省值 1。distance - 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.decay - 沿着光照距离的衰退量。缺省值 2。*/return new THREE.PointLight(color, intensity, distance, decay);
};
// 球形几何体
const createSphereGeometry = ({radius,widthSegments,heightSegments,phiStart,phiLength,thetaStart,thetaLength,
}) => {/*radius — 球体半径,默认为1。widthSegments — 水平分段数(沿着经线分段),最小值为3,默认值为32。heightSegments — 垂直分段数(沿着纬线分段),最小值为2,默认值为16。phiStart — 指定水平(经线)起始角度,默认值为0。。phiLength — 指定水平(经线)扫描角度的大小,默认值为 Math.PI * 2。thetaStart — 指定垂直(纬线)起始角度,默认值为0。thetaLength — 指定垂直(纬线)扫描角度大小,默认值为 Math.PI。*/return new THREE.SphereGeometry(radius,widthSegments,heightSegments,phiStart,phiLength,thetaStart,thetaLength);
};
// 球形几何体的材质
const createMeshLambertMaterial = (data) => {return new THREE.MeshLambertMaterial(data);
};
// 线几何体
const createLineGeometry = (points) => {const pointsVector3 = [];for (let i = 0; i < points.length; i++) {pointsVector3.push(new THREE.Vector3(points[i].x, points[i].y, points[i].z));}const geometry = new THREE.BufferGeometry().setFromPoints(pointsVector3);const line = new MeshLine();line.setGeometry(geometry);return line;
};
// 线几何体的材质
const createMeshLineMaterial = (data) => {return new MeshLineMaterial({lineWidth: data.linewidth,color: data.color || "white",dashArray: data.dashArray || 0,transparent: true,});
};
// 物体
const createMesh = (geometry, materialBasic) => {return new THREE.Mesh(geometry, materialBasic);
};
// 文本
const createText = ({ text, size, color }) => {let textClass = new SpriteText(text, size);textClass.color = color;return textClass;
};
// 轨道控制
const createControl = (camera, dom) => {return new OrbitControls(camera, dom);
};// 3d树布局算法 灵感来源 梯形/三角形转换为圆锥
const computedDataWeight = (data) => {let weight = 0;for (let i = 0; i < data.length; i++) {let item = data[i];if (item?.children?.length) {item.weight = computedDataWeight(item.children);weight += item.weight;} else {item.weight = 1;weight += 1;}}return weight;
};
const computedArcRArr = (data, pointInterval) => {let ArcRArr = [];let ArcData = [];let ArcWeight = [];formatTreeToArcData(data, ArcData);for (let i = 0; i < ArcData.length; i++) {let item = ArcData[i];let weight = 0;for (let j = 0; j < item.length; j++) {weight += item[j].weight;}ArcWeight.push(weight);}let R = computedArcR(pointInterval, ArcWeight[0]);// 半径算法for (let i = 0; i < ArcData.length; i++) {let item = ArcData[i];if (ArcWeight[i] < ArcWeight[0]) {// 不是完全层ArcRArr.push(R);} else {if (item.length > 1) {// 完全层let DValue = 0;item.forEach((weight) => {DValue += Math.floor(weight.weight / 2);});ArcRArr.push(((ArcWeight[i] - DValue) / ArcWeight[i]) * R);} else {ArcRArr.push(0);}}}return { ArcRArr, R };
};
const formatTreeToArcData = (data, ArcData, deep = 0) => {data.forEach((element) => {if (!ArcData[deep]) {ArcData[deep] = [];}ArcData[deep].push({label: element.label,point_uuid: element.point_uuid,weight: element.weight,});if (element?.children?.length) {formatTreeToArcData(element?.children, ArcData, deep + 1);}});
};
const computedArcR = (pointInterval, points) => {if (points === 1) {return pointInterval * 2;}let arcR =pointInterval /2 /Math.cos((Math.PI / 180) * (((points - 2) * 180) / points / 2));if (arcR < pointInterval) {arcR = pointInterval * 2;}return arcR;
};
const computedTreeStyleAuto = (style, ArcRArr, R) => {if (style.yr === "auto") {style.yr = ArcRArr.length === 1 ? R : R / (ArcRArr.length - 1);}style.startPositionY =((ArcRArr.length - 1) / 2) * style.yr + style.centerXYZ[1];
};
const computedPointPosition = (data,style,ArcRArr,startAngle = 0,endAngle = Math.PI * 2,deep = 0
) => {let totalWight = 0;for (let i = 0; i < data.length; i++) {totalWight += data[i].weight;}let AngleScope = endAngle - startAngle;let curAngle = startAngle;for (let i = 0; i < data.length; i++) {let item = data[i];let ratioAngle = (item.weight / totalWight) * AngleScope;item.position = {x:Math.sin(curAngle + ratioAngle / 2) * ArcRArr[deep] +style.centerXYZ[0],y:style.startPositionY -deep * (style.yr || 0) +style.centerXYZ[1],z:Math.cos(curAngle + ratioAngle / 2) * ArcRArr[deep] +style.centerXYZ[2],};if (item?.children?.length) {computedPointPosition(item?.children,style,ArcRArr,curAngle,curAngle + ratioAngle,deep + 1);}curAngle += ratioAngle;}
};// 计算camera初始位置
const computedCameraStyle = (style, dom, treeStyle, R) => {if (style.position === "auto") {style.position = {x: 0,y: treeStyle.yr * 1.5,z: R * 3,};}if (style.data === "auto") {style.data = {fov: 45,aspect: dom.clientWidth / dom.clientHeight,near: 0.1,far: R * R,};}if (style.lookAt === "auto") {style.lookAt = JSON.parse(JSON.stringify(treeStyle.centerXYZ));}
};const treeStyle = {centerXYZ: [0, 0, 0],yr: "auto",pointInterval: 10,
};
const cameraStyle = {position: "auto",data: "auto",lookAt: "auto",
};
const sphereMeshStyle = {geometry: {radius: 1,widthSegments: 320,heightSegments: 160,},material: {color: "#ffffff",wireframe: false, //是否将几何体渲染为线框,默认值为false(即渲染为平面多边形)},
};
const lineMeshStyle = {material: {color: "#ffffff",linewidth: 0.2,},
};
const textMeshStyle = {material: {size: 0.5,color: "#ffffff",},
};
let scene = null;
let camera = null;
let renderer = null;
const init = (rendererDom) => {let data = [{name: "顶点",children: [{name: "0",children: [{name: "0-0",children: [{name: "0-0-0",},{name: "0-0-1",children: [{name: "0-0-1-0",},],},{name: "0-0-2",},],},{name: "0-1",},{name: "0-2",children: [{name: "0-2-0",},{name: "0-2-1",},],},],},{name: "1",children: [{name: "1-0",},{name: "1-1",},{name: "1-2",children: [{name: "1-2-0",},{name: "1-2-1",},],},],},{name: "2",children: [{name: "2-0",children: [{name: "2-0-0",},{name: "2-0-1",},{name: "2-0-2",},],},{name: "2-1",children: [{name: "2-1-0",},{name: "2-1-1",},],},{name: "2-2",},],},]}];computedDataWeight(data);let { ArcRArr, R } = computedArcRArr(data, treeStyle.pointInterval);computedTreeStyleAuto(treeStyle, ArcRArr, R);computedPointPosition(data, treeStyle, ArcRArr);computedCameraStyle(cameraStyle, rendererDom, treeStyle, R);scene = createScene();camera = createPerspectiveCamera(cameraStyle.data);camera.position.set(cameraStyle.position.x,cameraStyle.position.y,cameraStyle.position.z);camera.lookAt(cameraStyle.lookAt[0],cameraStyle.lookAt[1],cameraStyle.lookAt[2]);renderer = createWebGLRenderer({dom: rendererDom,});createControl(camera, rendererDom);const axes = createAxesHelper(R);scene.add(axes);const ambientLight = createAmbientLight({ color: "#fff", intensity: 0.2 });scene.add(ambientLight);const pointLight = createPointLight({ color: "#fff", intensity: 1 });pointLight.position.set(R * 10, R * 10, R * 10);scene.add(pointLight);const sphereGeometrys = [];const textGeometrys = [];const lineGeometrys = [];initGeometrys(data, sphereGeometrys, textGeometrys, lineGeometrys);scene.add(...sphereGeometrys);scene.add(...textGeometrys);scene.add(...lineGeometrys);render();
};
const initGeometrys = (data, sphereGeometrys, textGeometrys, lineGeometrys, parentPosition) => {for (let i = 0; i < data.length; i++) {let item = data[i];const geometry = createSphereGeometry(sphereMeshStyle.geometry);const material = createMeshLambertMaterial(sphereMeshStyle.material);const mesh = createMesh(geometry, material);mesh.position.set(item.position.x, item.position.y, item.position.z);sphereGeometrys.push(mesh);const text = createText({text: item.name,size: textMeshStyle.material.size,color: textMeshStyle.material.color,});text.position.x = item.position.x;text.position.y = item.position.y + sphereMeshStyle.geometry.radius * 2;text.position.z = item.position.z;textGeometrys.push(text);if (parentPosition) {const lineGeometry = createLineGeometry([parentPosition,{ x: item.position.x, y: item.position.y, z: item.position.z },]);const lineMaterial = createMeshLineMaterial(lineMeshStyle.material);const lineMesh = createMesh(lineGeometry, lineMaterial);lineGeometrys.push(lineMesh);}if (item?.children?.length) {initGeometrys(item.children,sphereGeometrys,textGeometrys,lineGeometrys,{ x: item.position.x, y: item.position.y, z: item.position.z });}}
};
// 渲染
const render = () => {//循环调用requestAnimationFrame(render);renderer.render(scene, camera);
};onMounted(() => {let rendererDom = treeDom.value;init(rendererDom);
});
</script><template><div class="tree-new-page"><div class="tree-new" ref="treeDom"></div></div>
</template><style scoped lang="scss">
.tree-new-page {width: 100%;height: 100%;overflow: hidden;background-color: #000;position: relative;.tree-new {width: 100%;height: 100%;}
}
</style>
参考文档
three.js官方文档
three-spritetext文档
three.meshline文档
相关文章:

three.js实现3d球体树状结构布局——树状结构的实现
目录系列文章安装依赖基本分析实体类场景相机渲染器辅助线环境光点光源球形几何体球形几何体的材质线几何体线几何体的材质物体文本轨道控制实现效果实现源码参考文档系列文章 three.js实现3d球体树状结构布局——添加入场、出场、点击放大等动画 安装依赖 npm i three three…...

ChatGPT大解密:带您探讨机器学习背后的秘密、利用与发展
一、什么是机器学习?二、ChatGPT 的运作原理三、ChatGPT 生活利用1、自然语言处理2、翻译3、自动回复四、ChatGPT vs 其他相关技术五、ChatGPT 的未来1、未来发展2、职业取代3、客服人员4、翻译人员5、语言学家6、机遇与挑战六、结语这篇文章,将带着各位…...

3ds max2024带来了什么新功能(一)
文章目录1、安装2、操作界面3、快捷键(不冲突了)4、 修改器列表(可以搜索了)5、超级阵列功能(Array)6、超级布尔1、安装 传说3dmax2024有很多牛叉的改进二话不说,先安装按起来!这个…...

HNU-电路与电子学-实验3
实验三 模型机组合部件的实现(二)(实验报告格式案例) 班级 计XXXXX 姓名 wolf 学号 2021080XXXXX 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能&am…...

Hadoop MapReduce各阶段执行过程以及Python代码实现简单的WordCount程序
视频资料:黑马程序员大数据Hadoop入门视频教程,适合零基础自学的大数据Hadoop教程 文章目录Map阶段执行过程Reduce阶段执行过程Python代码实现MapReduce的WordCount实例mapper.pyreducer.py在Hadoop HDFS文件系统中运行Map阶段执行过程 把输入目录下文件…...

GitLab CI/CD 新书发布,助企业降本增效
前言 大家好,我是CSDN的拿我格子衫来, 昨天我的第一本书《GitLab CI/CD 从入门到实战》上架啦,这是业内第一本详细讲解GitLab CI/CD的书籍。 历经无数个日夜,最终开花结果。感触良多,今天就借这篇文章来谈一谈这本书的…...

【分享】如何写出整洁的代码?
文章目录前言1.为什么要保持代码整洁?1.1 所以从一开始就要保持整洁1.2 如何写出整洁的代码?2.命名3.类3.1单一职责3.2 开闭原则3.3 内聚4.函数4.1 只做一件事4.2 函数命名4.3 参数4.4 返回值4.5 怎样写出这样的函数?4.6 代码质量扫描工具5.测试5.1 TDD5.2 FIRST原则5.3 测试…...

视频剪辑:教你如何调整视频画面的大小。
大家应该都会调整图片的大小吧,那你们会调整视频画面的大小吗?我想,应该会有人不还不知道要调整的吧,今天就让小编来教大家一个方法怎样去调整视频画面的大小尺寸。 首先,我们要有以下材料: 一台电脑 【…...

操作系统概述
Overview Q1(Why):为什么要学操作系统?Q2(What):到底什么是操作系统?Q3(How):怎么学操作系统? 一.为什么要学操作系统? 学习操作系统…...

记录重启csdn
有太多收藏的链接落灰了,在此重启~ 1、社会 https://mp.weixin.qq.com/s/Uq0koAbMUk8OFZg2nCg_fg https://mp.weixin.qq.com/s/yCtLdEWSKVVAKhvLHxjeig https://zhuanlan.zhihu.com/p/569162335?utm_mediumsocial&utm_oi938179755602853888&ut…...

蓝牙耳机哪个品牌质量最好最耐用?蓝牙耳机排行榜10强推荐
现今,外出佩戴蓝牙耳机的人越来越多,各大品牌厂商对于蓝牙耳机各种性能的设计也愈发用心。那么,无线耳机哪个品牌音质好?下面,我来给大家推荐几款质量好的无线蓝牙耳机,可以当个参考。 一.南卡…...

mysql 双主架构详解
文章目录 一、背景二、MySQL双主(主主)架构方案三、MySQL双主架构图四、MySQL双主架构的优缺点五、MySQL双主架构,会存在什么问题?总结一、背景 MySQL 主从模式优缺点 容灾:主数据库宕机后,启动从数据库,用于故障切换 备份:防止数据丢失 读写分离:主数据库可以只负责…...

计算机指令系统基础 - 寻址方式详解
文章目录1 概述2 常见寻址方式2.1 立即寻址2.2 直接寻址2.3 间接寻址2.4 寄存器寻址2.5 寄存器间接寻址2.6 相对寻址2.7 变址寻址3 扩展3.1 操作码3.2 常见寄存器1 概述 计算机指令:指挥计算机工作的 指示 和 命令内容:通常一条 指令 包括两方面的内容 …...

React Three Fiber动画入门
使用静态对象和形状构建 3D 场景非常酷,但是当你可以使用动画使场景栩栩如生时,它会更酷。 在 3D 世界中,有一个称为角色装配的过程,它允许你创建称为骨架的特殊对象,其作用类似于骨骼和关节系统。 这些骨架连接到一块…...

为什么我推荐你使用 systemd timer 替代 cronjob?
概述 前几天在使用 Terraform cloud-init 批量初始化我的实验室 Linux 机器。正好发现有一些定时场景需要使用到 cronjob, 进一步了解到 systemd timer 完全可以替换 cronjob, 并且 systemd timer 有一些非常有趣的功能。 回归话题:为什么我推荐你使用 systemd t…...

elasticsearch基础6——head插件安装和web页面查询操作使用、ik分词器
文章目录一、基本了解1.1 插件分类1.2 插件管理命令二、分析插件2.1 es中的分析插件2.1.1 官方核心分析插件2.1.2 社区提供分析插件2.2 API扩展插件三、Head 插件3.1 安装3.2 web页面使用3.2.1 概览页3.2.1.1 unassigned问题解决3.2.2 索引页3.2.3 数据浏览页3.2.4 基本查询页3…...

【Linux】七、进程间通信(二)
目录 三、system V(IPC) 3.1 system V共享内存 3.1.1 共享内存的概念 3.1.2 共享内存的原理 3.1.3 创建共享内存(shmget ) 3.1.4 ftok函数 3.1.5 查看共享内存资源 3.1.6 创建共享内存测试代码 3.1.7 再次理解共享内存 3.1.8 释放共享内存(shm…...

Synchronized学习大总结
目录 1.synchronized特性 2.synchronized如何使用 3.synchronized的锁机制 1.synchronized特性 synchronized 是乐观锁,也是悲观锁,是轻量级锁(j基于自旋锁实现),也是重量级锁(基于挂起等待锁实现),它不是读写锁,是互斥锁,当一个线程抢到锁之后,其它线程阻塞等待,进入synchr…...

VN5620以太网测试——环境搭建篇
文章目录 前言一、新建以太网工程二、Port Configuration三、Link up四 Trace界面五、添加Ethernet Packet Builder六、添加ARP Packet七、添加Ethernet IG总结前言 CANoe(CAN open environment)VN5620 :是一个紧凑而强大的接口,用于以太网网络的分析、仿真、测试和验证。 …...

redis哨兵和集群部署手册
一、哨兵模式原理及作用 1.原理 哨兵(sentinel): 是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现 故障时,通过投票机制选择新的master并将所有slave连接到新的master。所以整个运行哨兵的集…...

ctfshow web入门 java 295 298-300
其他没啥好讲的,都是工具就通杀了 web295 漏洞地址 http://ip/S2-048/integration/saveGangster.action 这里我们可以看到他是解析了 尝试使用网上的payload %{(#dmognl.OgnlContextDEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess#dm):((#container#cont…...

SWIG包装器使用指南——(四)C#使用SWIG简介与实践
SWIG系列:http://t.csdn.cn/cIAcr 文章目录一、简介二、全局函数、变量、常量三、继承四、传递指针、引用、数组与值五、基本类型的指针与引用六、基本类型的数组七、基本类型的默认map规则八、常用的typemap方法九、代码插入十、实践10.1 如何映射Foo*&到ref F…...

HashTable, HashMap 和 ConcurrentHashMap
HashTable, HashMap 和 ConcurrentHashMap 都是 Java 集合框架中的类,用于存储和操作键值对。它们之间存在一些关键区别,如下所示: 1.同步性: HashTable:线程安全,所有的方法都是同步的(synchr…...

ToBeWritten之IoT 技战法
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...

基于ASP.NET开发的医院手术麻醉信息管理系统源码 项目源码
系统主要功能介绍: 门诊科室管理系统:手术快速申请、手术申请、手术审核 麻醉科管理系统:手术安排、术后处方、术后小结、PCS实施及管理记录、手术流程 手术护理系统:手术安排、安排临时手术、添加急诊手术、局麻手术护理、整体护…...

伪加密超具体破解办法,直击原理底层,细致演示!!!
前言: 由于我自己目前在misc和取证工作中,也遇到很多压缩包的问题,我个人非常喜欢做压缩包的题目,但也会遇到伪加密问题难以破解,全网ctf教程我都看完了,但是都觉得不够具体,所以我写一篇博客&…...

ChatGPT大规模封锁亚洲地区账号
我是卢松松,点点上面的头像,欢迎关注我哦! 在毫无征兆的情况下,从3月31日开始OpenAI大规模封号,而且主要集中在亚洲地区,特别是ip地址在台湾、日本、香港三地的,命中率目测40%。新注册的账号、…...

脂肪酸脂质Myristic acid PEG NHS,Myristic-acid PEG NHS ester,肉豆蔻酸PEG活性酯,具有优异疏水性
一、基础产品数据: 中文名:肉豆蔻酸PEG N-羟基琥珀酰亚胺,肉豆蔻酸PEG活性酯 英文名:Myristic acid PEG NHS,Myristic-acid PEG NHS ester,Myristic acid PEG SE 结构式(Structural)…...

MFC - CFormView类学习1
CFormView简介 MFC提供了一个名为CFormView的特殊视图类,我们称其为表单视图。表单视图是指用控件来输入和输出数据的视图,用户可以方便地在表单视图中使用控件。表单视图具有对话框和滚动视图的特性,它使程序看起来象是一个具有滚动条的对话…...

图像预处理方法
图像预处理 膨胀腐蚀概述 ⚫ 膨胀、腐蚀属于形态学的操作, 简单来说就是基于形状的一系列图像处理操作 ⚫ 膨胀腐蚀是基于高亮部分(白色)操作的, 膨胀是対高亮部分进行膨胀, 类似“领域扩张”, 腐蚀是高亮部分被腐蚀, 类似“领域被蚕食” ⚫ 膨胀腐蚀的应用和功能: 消除噪声…...