Threejs中使用A*算法寻路导航

 

<!DOCTYPE html>
<html><head><title>Threejs中使用A*算法寻路导航,Threejs室内室外地图导航</title><script type="text/javascript" src="libs/three.js"></script><script type="text/javascript" src="libs/OrbitControls.js"></script><script type="text/javascript" charset="UTF-8" src="libs/other/Tween.min.js"></script><script type="text/javascript" charset="UTF-8" src="libs/three/loaders/GLTFLoader.js"></script><script type="text/javascript" src="libs/OBJLoader.js"></script><script type="text/javascript" src="libs/MTLLoader.js"></script><script type="text/javascript" src="libs/util.js"></script><script type="text/javascript" src="libs/util/dat.gui.js"></script><script type="text/javascript" src="libs/astar.js"></script><style>body {margin: 0;overflow: hidden;}</style></head><body><div id="webgl-output"></div><script type="text/javascript">var camera;var renderer;var clock = new THREE.Clock();var mixer = new THREE.AnimationMixer();var clipAction;var animationClip;var length = 36;var ws = 2;var graph = []; // 记录地图var meshArr = new Array(); // 记录障碍物对象数据var meshxy = [{"x": 35,"y": 7},{"x": 35,"y": 7},{"x": 35,"y": 9},{"x": 35,"y": 11},{"x": 29,"y": 11},{"x": 29,"y": 13},{"x": 33,"y": 13},{"x": 33,"y": 11},{"x": 33,"y": 9},{"x": 33,"y": 5},{"x": 33,"y": 7},{"x": 29,"y": 5},{"x": 31,"y": 5},{"x": 31,"y": 11},{"x": 27,"y": 5},{"x": 25,"y": 5},{"x": 25,"y": 7},{"x": 25,"y": 9},{"x": 25,"y": 11},{"x": 25,"y": 13},{"x": 23,"y": 9},{"x": 21,"y": 9},{"x": 19,"y": 9},{"x": 19,"y": 11},{"x": 19,"y": 13},{"x": 15,"y": 9},{"x": 13,"y": 7},{"x": 13,"y": 9},{"x": 13,"y": 11},{"x": 11,"y": 7},{"x": 13,"y": 5},{"x": 11,"y": 5},{"x": 7,"y": 5},{"x": 5,"y": 5},{"x": 5,"y": 7},{"x": 7,"y": 7},{"x": 7,"y": 9},{"x": 7,"y": 11},{"x": 5,"y": 11},{"x": 5,"y": 9},{"x": 7,"y": 15},{"x": 7,"y": 17},{"x": 7,"y": 19},{"x": 11,"y": 23},{"x": 11,"y": 17},{"x": 11,"y": 21},{"x": 11,"y": 19},{"x": 17,"y": 25},{"x": 17,"y": 27},{"x": 17,"y": 29},{"x": 19,"y": 25},{"x": 21,"y": 25},{"x": 17,"y": 21},{"x": 17,"y": 23},{"x": 17,"y": 19},{"x": 15,"y": 19},{"x": 13,"y": 19},{"x": 7,"y": 29},{"x": 7,"y": 31},{"x": 7,"y": 33},{"x": 9,"y": 33},{"x": 13,"y": 33},{"x": 11,"y": 33},{"x": 13,"y": 31},{"x": 13,"y": 29},{"x": 15,"y": 33},{"x": 17,"y": 33},{"x": 19,"y": 33},{"x": 21,"y": 33},{"x": 25,"y": 29},{"x": 25,"y": 31},{"x": 25,"y": 33},{"x": 27,"y": 29},{"x": 29,"y": 29},{"x": 29,"y": 23},{"x": 27,"y": 23},{"x": 25,"y": 23},{"x": 29,"y": 21},{"x": 29,"y": 19},{"x": 33,"y": 19},{"x": 33,"y": 21},{"x": 33,"y": 23},{"x": 33,"y": 25},{"x": 33,"y": 27},{"x": 33,"y": 29},{"x": 33,"y": 31},{"x": 33,"y": 33},{"x": 31,"y": 35},{"x": 29,"y": 35},{"x": 27,"y": 35},{"x": 25,"y": 35},{"x": 7,"y": 23},{"x": 11,"y": 15},{"x": 9,"y": 15},{"x": 35,"y": 9},{"x": 35,"y": 11},{"x": 29,"y": 11},{"x": 29,"y": 13},{"x": 33,"y": 13},{"x": 33,"y": 11},{"x": 33,"y": 9},{"x": 33,"y": 5},{"x": 33,"y": 7},{"x": 29,"y": 5},{"x": 31,"y": 5},{"x": 31,"y": 11},{"x": 27,"y": 5},{"x": 25,"y": 5},{"x": 25,"y": 7},{"x": 25,"y": 9},{"x": 25,"y": 11},{"x": 25,"y": 13},{"x": 23,"y": 9},{"x": 21,"y": 9},{"x": 19,"y": 9},{"x": 19,"y": 11},{"x": 19,"y": 13},{"x": 15,"y": 9},{"x": 13,"y": 7},{"x": 13,"y": 9},{"x": 13,"y": 11},{"x": 11,"y": 7},{"x": 13,"y": 5},{"x": 11,"y": 5},{"x": 7,"y": 5},{"x": 5,"y": 5},{"x": 5,"y": 7},{"x": 7,"y": 7},{"x": 7,"y": 9},{"x": 7,"y": 11},{"x": 5,"y": 11},{"x": 5,"y": 9},{"x": 7,"y": 15},{"x": 7,"y": 17},{"x": 7,"y": 19},{"x": 11,"y": 23},{"x": 11,"y": 17},{"x": 11,"y": 21},{"x": 11,"y": 19},{"x": 17,"y": 25},{"x": 17,"y": 27},{"x": 17,"y": 29},{"x": 19,"y": 25},{"x": 21,"y": 25},{"x": 17,"y": 21},{"x": 17,"y": 23},{"x": 17,"y": 19},{"x": 15,"y": 19},{"x": 13,"y": 19},{"x": 7,"y": 29},{"x": 7,"y": 31},{"x": 7,"y": 33},{"x": 9,"y": 33},{"x": 13,"y": 33},{"x": 11,"y": 33},{"x": 13,"y": 31},{"x": 13,"y": 29},{"x": 15,"y": 33},{"x": 17,"y": 33},{"x": 19,"y": 33},{"x": 21,"y": 33},{"x": 25,"y": 29},{"x": 25,"y": 31},{"x": 25,"y": 33},{"x": 27,"y": 29},{"x": 29,"y": 29},{"x": 29,"y": 23},{"x": 27,"y": 23},{"x": 25,"y": 23},{"x": 29,"y": 21},{"x": 29,"y": 19},{"x": 33,"y": 19},{"x": 33,"y": 21},{"x": 33,"y": 23},{"x": 33,"y": 25},{"x": 33,"y": 27},{"x": 33,"y": 29},{"x": 33,"y": 31},{"x": 33,"y": 33},{"x": 31,"y": 35},{"x": 29,"y": 35},{"x": 27,"y": 35},{"x": 25,"y": 35},{"x": 7,"y": 23},{"x": 11,"y": 15},{"x": 9,"y": 15},{"x": 35,"y": 9},{"x": 35,"y": 11},{"x": 29,"y": 11},{"x": 29,"y": 13},{"x": 33,"y": 13},{"x": 33,"y": 11},{"x": 33,"y": 9},{"x": 33,"y": 5},{"x": 33,"y": 7},{"x": 29,"y": 5},{"x": 31,"y": 5},{"x": 31,"y": 11},{"x": 27,"y": 5},{"x": 25,"y": 5},{"x": 25,"y": 7},{"x": 25,"y": 9},{"x": 25,"y": 11},{"x": 25,"y": 13},{"x": 23,"y": 9},{"x": 21,"y": 9},{"x": 19,"y": 9},{"x": 19,"y": 11},{"x": 19,"y": 13},{"x": 15,"y": 9},{"x": 13,"y": 7},{"x": 13,"y": 9},{"x": 13,"y": 11},{"x": 11,"y": 7},{"x": 13,"y": 5},{"x": 11,"y": 5},{"x": 7,"y": 5},{"x": 5,"y": 5},{"x": 5,"y": 7},{"x": 7,"y": 7},{"x": 7,"y": 9},{"x": 7,"y": 11},{"x": 5,"y": 11},{"x": 5,"y": 9},{"x": 7,"y": 15},{"x": 7,"y": 17},{"x": 7,"y": 19},{"x": 11,"y": 23},{"x": 11,"y": 17},{"x": 11,"y": 21},{"x": 11,"y": 19},{"x": 17,"y": 25},{"x": 17,"y": 27},{"x": 17,"y": 29},{"x": 19,"y": 25},{"x": 21,"y": 25},{"x": 17,"y": 21},{"x": 17,"y": 23},{"x": 17,"y": 19},{"x": 15,"y": 19},{"x": 13,"y": 19},{"x": 7,"y": 29},{"x": 7,"y": 31},{"x": 7,"y": 33},{"x": 9,"y": 33},{"x": 13,"y": 33},{"x": 11,"y": 33},{"x": 13,"y": 31},{"x": 13,"y": 29},{"x": 15,"y": 33},{"x": 17,"y": 33},{"x": 19,"y": 33},{"x": 21,"y": 33},{"x": 25,"y": 29},{"x": 25,"y": 31},{"x": 25,"y": 33},{"x": 27,"y": 29},{"x": 29,"y": 29},{"x": 29,"y": 23},{"x": 27,"y": 23},{"x": 25,"y": 23},{"x": 29,"y": 21},{"x": 29,"y": 19},{"x": 33,"y": 19},{"x": 33,"y": 21},{"x": 33,"y": 23},{"x": 33,"y": 25},{"x": 33,"y": 27},{"x": 33,"y": 29},{"x": 33,"y": 31},{"x": 33,"y": 33},{"x": 31,"y": 35},{"x": 29,"y": 35},{"x": 27,"y": 35},{"x": 25,"y": 35},{"x": 7,"y": 23},{"x": 11,"y": 15},{"x": 9,"y": 15},{"x": 19,"y": 21},{"x": 21,"y": 21},{"x": 21,"y": 19},{"x": 29,"y": 27},{"x": 29,"y": 25}]; // 记录障碍坐标物数据var lineArr = new Array(); // 记录路网数据var meshbool = false; // 显示障碍物var linebool = false; // 显示路网var resultArray = new Array();var isCaculate = false;function init() {// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。var scene = new THREE.Scene();var urls = ['assets/textures/cubemap/flowers/posx.jpg','assets/textures/cubemap/flowers/negx.jpg','assets/textures/cubemap/flowers/posy.jpg','assets/textures/cubemap/flowers/negy.jpg','assets/textures/cubemap/flowers/posz.jpg','assets/textures/cubemap/flowers/negz.jpg'];var cubeLoader = new THREE.CubeTextureLoader();scene.background = cubeLoader.load(urls);// 创建一个摄像机,它定义了我们正在看的地方camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 1000);// 将摄像机对准场景的中心camera.position.x = 60;camera.position.y = 35;camera.position.z = 60;camera.lookAt({x: 0,y: 5,z: -20});var orbit = new THREE.OrbitControls(camera);orbit.target = camera.position;orbit.update();// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景// initialize basic rendererrenderer = initRenderer({antialias: true,logarithmicDepthBuffer: true,});// 将平面添加到场景中var plane = createPlaneGeometryBasicMaterial();scene.add(plane);// 在屏幕上显示坐标轴var axes = new THREE.AxesHelper(100);scene.add(axes);scene.add(new THREE.AmbientLight(0x666666));scene.add(new THREE.AmbientLight("#ffffff", 1));initModel();// initPeople();initGround();initGrid();var i = 0;function tweenComplete() {if (i < points.length) {switch (i) {case 0:aaa.rotateY(Math.PI);break;case 1:case 5:case 8:case 9:aaa.rotateY(-0.5 * Math.PI);break;case 2:case 3:case 4:case 6:case 7:aaa.rotateY(0.5 * Math.PI);break;case 10:mixer.stopAllAction();break;}tween = new TWEEN.Tween(points[i]).to(points[i + 1], 3000).easing(TWEEN.Easing.Linear.None).onUpdate(function() {aaa.position.set(this.x, this.y, this.z);}).onComplete(tweenComplete).start();i++;}}// 使用GUI调试库var controls = new function() {this.clickBool = false;this.displayRoadGrid = function() {for (var i = 0; i < lineArr.length; i++) {if (linebool) {// 显示路网scene.add(lineArr[i].obj);} else {// 隐藏路网var obj = scene.getObjectByName(lineArr[i].name);scene.remove(obj);}}linebool = !linebool}this.displayObstacles = function() {for (var i = 0; i < meshArr.length; i++) {if (meshbool) {// 显示障碍物scene.add(meshArr[i].obj);} else {// 隐藏障碍物var obj = scene.getObjectByName(meshArr[i].name);scene.remove(obj);}}meshbool = !meshbool}this.outputObstacles = function() {for (var i = 0; i < meshArr.length; i++) {meshxy.push({x: meshArr[i].x,y: meshArr[i].y})}console.log(meshArr)console.log(lineArr)console.log(meshxy)localStorage.setItem('meshArr', JSON.stringify(meshArr));localStorage.setItem('lineArr', JSON.stringify(lineArr));localStorage.setItem('meshxy', JSON.stringify(meshxy));}}var gui = new dat.GUI();// 隐藏显示障路网gui.add(controls, 'displayRoadGrid');// 隐藏显示障碍物gui.add(controls, 'displayObstacles');// 输出障碍物对象gui.add(controls, 'outputObstacles');gui.add(controls, "clickBool");// 启动动画renderScene();// 添加模型function initModel() {var mtlLoader = new THREE.MTLLoader();mtlLoader.setPath("assets/models/obj_mtl/")mtlLoader.load('city.mtl', function(materials) {materials.preload();var objLoader = new THREE.OBJLoader();objLoader.setMaterials(materials);objLoader.load('assets/models/obj_mtl/city.obj', function(object) {var mesh = object;mesh.scale.set(3, 3, 3);mesh.position.set(18, 0, 18);scene.add(mesh);});});}// 添加人物模型function initPeople() {var loader = new THREE.GLTFLoader();loader.load('assets/models/CesiumMan/CesiumMan.gltf', function(result) {result.scene.scale.set(1, 1, 1);result.scene.translateY(0);aaa = result.scene;scene.add(result.scene);tweenComplete();mixer = new THREE.AnimationMixer(result.scene);animationClip = result.animations[0];clipAction = mixer.clipAction(animationClip).play();animationClip = clipAction.getClip();});}// 创建一个地面并设置草坪材质function createPlaneGeometryBasicMaterial() {var textureLoader = new THREE.TextureLoader();var cubeMaterial = new THREE.MeshStandardMaterial({map: textureLoader.load("assets/textures/stone/cd.jpg"),});cubeMaterial.map.wrapS = THREE.RepeatWrapping;cubeMaterial.map.wrapT = THREE.RepeatWrapping;cubeMaterial.map.repeat.set(18, 18)// 创建地平面并设置大小var planeGeometry = new THREE.PlaneGeometry(500, 500);var plane = new THREE.Mesh(planeGeometry, cubeMaterial);// 设置平面位置并旋转plane.rotation.x = -0.5 * Math.PI;plane.position.x = 0;plane.position.z = 0;return plane;}// 绘制线路function initLine(pArr) {var points = [];var geometry = new THREE.Geometry();for (var i = 0; i < pArr.length; i++) {var randomX = pArr[i].x;var randomY = pArr[i].y;var randomZ = pArr[i].z;var vector = new THREE.Vector3(randomX, randomY, randomZ);geometry.vertices.push(vector);points.push(vector);}var material = new THREE.LineBasicMaterial({color: 0x0000FF});var line = new THREE.Line(geometry, material);scene.add(line);return points;}// 绘制路网function initGround() {var geometry = new THREE.Geometry();geometry.vertices.push(new THREE.Vector3(0, 0, 0));geometry.vertices.push(new THREE.Vector3(length, 0, 0));for (var i = 0; i <= length / ws; i++) {var material = new THREE.LineBasicMaterial({color: 0x808080});var line = new THREE.Line(geometry, material);line.position.z = i * ws;line.name = "line_" + i;lineArr.push({name: "line_" + i,obj: line});scene.add(line);var line = new THREE.Line(geometry, material);line.position.x = i * ws;line.position.z = length;line.rotation.y = 90 * Math.PI / 180;line.name = "line_" + i + 180;lineArr.push({name: "line_" + i + 180,obj: line});scene.add(line);}}// 初始化障碍物随机function initGrid() {for (var i = 0; i < length / ws; i++) {var nodeRow = [];for (var j = 0; j < length / ws; j++) {nodeRow.push(1);}graph.push(nodeRow);}if (meshxy.length > 0) {for (var i = 0; i < meshxy.length; i++) {initObstacles(meshxy[i].x, meshxy[i].y);}} else {for (var i = 0; i < length / ws; i++) {var nodeRow = [];for (var j = 0; j < length / ws; j++) {var salt = Math.random() * 7;if (salt > 2) {nodeRow.push(1);} else {nodeRow.push(0);}if (salt <= 2) {var cube = new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshBasicMaterial({color: 0xC0C0C0}));let x = ws * j + ws / 2;let z = ws * i + ws / 2;cube.position.set(x, 1.2, z);scene.add(cube);}}graph.push(nodeRow);}}}//计算路径function caculatePath(resultArray) {var maps = new Graph(graph); // 地图var startX = parseInt(resultArray[0].position.z / ws);var startY = parseInt(resultArray[0].position.x / ws);var endX = parseInt(resultArray[1].position.z / ws);var endY = parseInt(resultArray[1].position.x / ws);var start = maps.grid[startX][startY];var end = maps.grid[endX][endY];result = astar.search(maps, start, end);if (result.length == 0) {alert("无可到达路径");cleanSphere();return;}var nArr = [{x: resultArray[0].position.x,z: resultArray[0].position.z,y: 1.2}];for (var i = 0; i < result.length; i++) {let d = {x: result[i].y * ws + ws / 2,y: 1.2,z: result[i].x * ws + ws / 2,}nArr.push(d);}initLine(nArr);}//清除小球function cleanSphere() {let child = scene.children; //获取场景中的所有子对象for (var i = 0; i < child.length; i++) {if (child[i].geometry instanceof THREE.SphereGeometry) { //几何对象是球体几何scene.remove(child[i]); //从场景中移除i--;}}isCaculate = false;}//初始球体function initSphere(x, z) {if (isCaculate) {cleanSphere();}var geometry = new THREE.SphereGeometry(ws / 2, 30, 30); //球体几何var material = new THREE.MeshBasicMaterial({color: 0xffff00}); //网格基础材料if (resultArray.length == 0) {var sphere = new THREE.Mesh(geometry, material);sphere.position.x = x;sphere.position.y = 1;sphere.position.z = z;resultArray.push(sphere);scene.add(sphere);} else if (resultArray[0].position.x != x || resultArray[0].position.z != z) {var sphere = new THREE.Mesh(geometry, material);sphere.position.x = x;sphere.position.y = 1;sphere.position.z = z;resultArray.push(sphere);scene.add(sphere);caculatePath(resultArray);isCaculate = true;resultArray = new Array();}}// 绘制障碍物function initObstacles(x, z) {var name = "mesh_" + x + z;var obj = scene.getObjectByName(name);if (obj) {scene.remove(obj);for (var i = 0; i < meshArr.length; i++) {if (meshArr[i].name == name) {meshArr.splice(i, 1);}}graph[parseInt(z / ws)][parseInt(x / ws)] = 1;} else {var geometry = new THREE.BoxGeometry(ws, ws, ws); //球体几何var material = new THREE.MeshBasicMaterial({color: 0xff0000});var sphere = new THREE.Mesh(geometry, material);sphere.position.x = x;sphere.position.y = 1;sphere.position.z = z;sphere.name = name;scene.add(sphere);meshArr.push({name: name,obj: sphere,x: x,y: z,});graph[parseInt(z / ws)][parseInt(x / ws)] = 0;}}// 拾取对象function pickupObjects(event) {// 点击屏幕创建一个向量var raycaster = new THREE.Raycaster();var vector = new THREE.Vector2((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1);var fxl = new THREE.Vector3(0, 1, 0);var groundplane = new THREE.Plane(fxl, 0);raycaster.setFromCamera(vector, camera);var ray = raycaster.ray;let intersects = ray.intersectPlane(groundplane);let x = intersects.x;let z = intersects.z;if (x < 0 || z < 0 || length < z || length < x) {return;}var k, m;for (var i = 0; i < length; i += ws) {if (x >= i && x < i + ws) {k = i + ws / 2;}}for (var j = 0; j < length; j += ws) {if (z >= j && z < j + ws) {m = j + ws / 2;}}if (controls.clickBool) {initSphere(k, m); //初始化球体} else {initObstacles(k, m);}}document.addEventListener('click', pickupObjects, false); //监听单击拾取对象初始化球体// 动画渲染var step = 5;function renderScene() {TWEEN.update();var delta = clock.getDelta();orbit.update();mixer.update(delta);// 使用requestAnimationFrame函数进行渲染requestAnimationFrame(renderScene);renderer.render(scene, camera);}// 渲染的场景renderer.render(scene, camera);// 创建一个球形几何体function createSphereGeometryLambertMaterial(point) {// 创建一个球体var sphereGeometry = new THREE.SphereGeometry(0.2, 20, 20);var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x7777ff,wireframe: true});var sphereMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);// 设置该物体投射阴影sphere.castShadow = true;// 位置范围sphere.position.x = point.x;sphere.position.y = point.y;sphere.position.z = point.z;return sphere;}}window.onload = init;function onResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}// 监听调整大小事件window.addEventListener('resize', onResize, false);</script></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1551685.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

zabbix7.0监控linux主机案例详解

前言 服务端配置 链接: rocky9.2部署zabbix服务端的详细过程 环境 主机ip应用zabbix-server192.168.10.11zabbix本体zabbix-client192.168.10.12zabbix-agent zabbix-server(服务端已配置) 具体实现过程 zabbix-client配置 安装zabbix-agent 添加扩展包 dnf -y instal…

AD软件的分屏显示功能

1.鼠标右键点击上面的窗格&#xff0c;选择“垂直分布”&#xff0c;即可以将AD软件分屏&#xff0c;左边选择原理图&#xff0c;右边选择PCB即可以方便去设计PCB的布局。实现原理图和pcb文件的同时查看。 还可以建立起2个图之间的联动关系。 比如我们在电路图里面选择stm32 m…

风险函数梳理工具

风险函数梳理工具 在日常的软件开发工作中&#xff0c;代码的安全性和质量至关重要。然而&#xff0c;面对庞大的代码库&#xff0c;手动查找潜在的风险函数不仅耗时&#xff0c;而且容易出错。特别是在团队协作中&#xff0c;代码审查和重构工作往往占据了大量宝贵的时间&…

心理咨询预约管理系统(含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 心理咨询预约管理系统2拥有三个角色&#xff1a; 管理员端 首页 系统近况&#xff08;咨询师和注册来访者数量&#xff0c;预约数量&#xff09; 显示最新的消息、留言和公告&#xff0…

软件测试学习笔记丨Pytest 学习指南

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/32336 基本介绍 pytest框架是一个成熟&#xff0c;全面的测试框架&#xff0c;具有非常丰富的第三方插件&#xff0c;并且可以自定义扩展 比如&#xff1a;pytest-selenium , pytest-html ,…

spring模块都有哪些

Spring 框架是一个庞大而灵活的生态系统&#xff0c;它包含了多个模块&#xff0c;每个模块都提供了特定的功能和服务。以下是一些主要的 Spring 模块&#xff1a; Spring Core&#xff1a; 核心容器&#xff0c;提供了 IoC&#xff08;控制反转&#xff09;和 DI&#xff08;…

推荐4个精准高效的录音转文字软件。

录音转文字在很多的场景中都能够为我们提供便利&#xff0c;比如&#xff1a;可以将课堂录音转换为文字&#xff0c;方便复习和整理笔记&#xff0c;可以将会议录音转换为文字&#xff0c;快速准确地记录内容&#xff0c;可以将采访录音转成文字&#xff0c;提高新闻稿件的撰写…

被Karpathy誉为“蕴藏着类似ChatGPT的机会的AI产品Notebook LM”,它到底做对了什么?

就在昨天&#xff0c;Karpathy在X上连续发布了多条安利帖&#xff0c;强烈地给大家推荐一个AI产品NotebookLM。 嘶&#xff5e;给周围人疯狂种草并不稀奇&#xff0c;但Karpathy的推荐理由给NotebookLM戴了一个高帽子-他提到这款产品让人联想到ChatGPT。 这种就令人好奇&#…

JAVA开源项目 大学生就业招聘系统 计算机毕业设计

本文项目编号 T 058 &#xff0c;文末自助获取源码 \color{red}{T058&#xff0c;文末自助获取源码} T058&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 企…

DRF实操——项目部署

DRF实操——项目部署 一、Mysql集群1. 集群方式1)Replication集群2)PXC集群2. Docker安装PXC知识补充:具名数据卷创建docker容器django后端接口服务二、Nginx概述作用安装配置三、uWSGI1. 概述2. 项目的配置3. 将本地项目及环境打包到服务器4. uwsgi的安装与启动5. 使用uwsg…

Vue Mini基于 Vue 3 的小程序框架

新的小程序框架 https://vuemini.org/ Vue Mini 是一个基于 Vue 3 的小程序框架&#xff0c;它允许开发者利用 Vue 3 的强大功能来构建微信小程序。Vue Mini 的核心优势在于它的响应式系统和组合式 API&#xff0c;这些特性让开发者能够以一种更声明式、更高效的方式来编写和…

今天不止是A股疯,这家国产大模型也疯了!AI人:1亿小目标已实现

这两天有个很神奇的现象&#xff0c;就是有两个从来不碰A股的小伙伴&#xff0c;竟然跑过来问我——“现在上车A股还有机会吗&#xff1f;” 放心吧&#xff0c;我当然不可能在这里回答这个问题的&#xff0c;否则就你懂的。 今天这篇文章不是讨论A股的。而是我无意间发现&am…

脸爱云管理系统存在任意文件上传漏洞

漏洞描述 脸爱云一脸通智慧管理平台是一套功能强大、运行稳定、操作简单方便、用户界面美观的一脸通系统。该平台整合了人脸识别技术和智能化解决方案&#xff0c;可以实现识别和管理个体身份&#xff0c;为各种场景提供便捷的身份验证和管理功能。其存在任意文件上传漏洞&…

记一次vue-cli老项目的打包时长优化

记一次vue-cli老项目的打包时长优化 背景 这是一个基于 vue-cli 的 vue2 的老项目&#xff0c;比较久远&#xff0c;一般Jenkins中打包时间都在 5-6min 左右&#xff0c;基本能够接受。 近来由于项目原因&#xff0c;在该项目中加入了一些在打包时动态生成的js文件以做“缓存…

信号量SEM

前提 1.信号量的本质是一把计数器 2.申请信号本质就是预订资源 3.PV操作是原子的! 将一个公共资源当做整体访问-->锁 如果公共资源不当做整体使用&#xff0c;多进程可以并发的访问公共资源&#xff0c;但不是同一个区域&#xff0c;为了将资源均分&#xff0c;所以有了…

PE节表中是否存在misc.VirtualSize 比SizeofRawData还要大的情况

确实是存在的,这是win10自带记事本,可以看到 确实是大.所以在申请imagebuffer的时候,还是需要比较大小.但是在还原的时候.只考虑sizeofRawData即可>

Python查漏补缺

1.冒泡排序 时间复杂度O&#xff08;n^2) 选择、插入都是 def bubble(data, reverse):for i in range(len(data)-1):for j in range(len(data)-i-1):if data[j] > data[j1]:data[j], data[j1] data[j1], data[j]if reverse:data.reverse()return data 2.快速排序 时间…

QT将QBytearray的data()指针赋值给结构体指针变量后数据不正确的问题

1、问题代码 #include <QCoreApplication>#pragma pack(push, 1) typedef struct {int a; // 4字节float b; // 4字节char c; // 1字节int *d; // 8字节 }testStruct; #pragma pack(pop)#include <QByteArray> #include <QDebug>int main() {testStruct …

ros2安装完成后重要的一步

安装完成ros2之后&#xff0c;每次打开新的终端都需要 source /opt/ros/humble/setup.bash 为了解决这个为题&#xff0c;我们需要做如下操作,避免每次打开一个新的在终端都要设置。 在文件的最后一行添加 source /opt/ros/foxy/setup.bash

职称评审难在哪?

没有项目业绩资料&#xff1f; 社保不符合&#xff1f; 看不懂评审文件&#xff1f; 申报材料不会做&#xff1f; 论文没地发表&#xff1f; 有这些疑问的 评论区滴滴