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

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大解密:带您探讨机器学习背后的秘密、利用与发展

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

3ds max2024带来了什么新功能(一)

文章目录1、安装2、操作界面3、快捷键&#xff08;不冲突了&#xff09;4、 修改器列表&#xff08;可以搜索了&#xff09;5、超级阵列功能&#xff08;Array&#xff09;6、超级布尔1、安装 传说3dmax2024有很多牛叉的改进二话不说&#xff0c;先安装按起来&#xff01;这个…...

HNU-电路与电子学-实验3

实验三 模型机组合部件的实现&#xff08;二&#xff09;&#xff08;实验报告格式案例&#xff09; 班级 计XXXXX 姓名 wolf 学号 2021080XXXXX 一、实验目的 1&#xff0e;了解简易模型机的内部结构和工作原理。 2&#xff0e;分析模型机的功能&am…...

Hadoop MapReduce各阶段执行过程以及Python代码实现简单的WordCount程序

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

GitLab CI/CD 新书发布,助企业降本增效

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

【分享】如何写出整洁的代码?

文章目录前言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 测试…...

视频剪辑:教你如何调整视频画面的大小。

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

操作系统概述

Overview Q1&#xff08;Why&#xff09;:为什么要学操作系统&#xff1f;Q2&#xff08;What&#xff09;&#xff1a;到底什么是操作系统&#xff1f;Q3&#xff08;How&#xff09;&#xff1a;怎么学操作系统&#xff1f; 一.为什么要学操作系统&#xff1f; 学习操作系统…...

记录重启csdn

有太多收藏的链接落灰了&#xff0c;在此重启&#xff5e; 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强推荐

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

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 概述 计算机指令&#xff1a;指挥计算机工作的 指示 和 命令内容&#xff1a;通常一条 指令 包括两方面的内容 …...

React Three Fiber动画入门

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

为什么我推荐你使用 systemd timer 替代 cronjob?

概述 前几天在使用 Terraform cloud-init 批量初始化我的实验室 Linux 机器。正好发现有一些定时场景需要使用到 cronjob, 进一步了解到 systemd timer 完全可以替换 cronjob, 并且 systemd timer 有一些非常有趣的功能。 回归话题&#xff1a;为什么我推荐你使用 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&#xff08;IPC&#xff09; 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.原理 哨兵&#xff08;sentinel&#xff09;&#xff1a; 是一个分布式系统&#xff0c;用于对主从结构中的每台服务器进行监控&#xff0c;当出现 故障时&#xff0c;通过投票机制选择新的master并将所有slave连接到新的master。所以整个运行哨兵的集…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...