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

学习threejs,使用Physijs物理引擎,使用DOFConstraint自由度约束,模拟小车移动

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录

  • 一、🍀前言
    • 1.1 ☘️Physijs 物理引擎
      • 1.1.1 ☘️代码示例
      • 1.1.2 ☘️核心方法/属性
      • 1.1.3 ☘️网格对象
      • 1.1.4 ☘️约束
      • 1.1.4 ☘️约束、材质Materials、暂停/恢复模拟、场景配置、更新对象的位置和旋转使用样例
        • 1.1.4.1 ☘️约束使用样例
        • 1.1.4.2 ☘️材质Materials使用样例
        • 1.1.4.3 ☘️暂停/恢复模拟使用样例
        • 1.1.4.4 ☘️场景配置使用样例
        • 1.1.4.5 ☘️更新对象的位置和旋转使用样例
  • 二、🍀使用Physijs物理引擎,使用DOFConstraint自由度约束,模拟小车移动
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用Physijs物理引擎,使用DOFConstraint自由度约束,模拟小车移动,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️Physijs 物理引擎

Three.js 的 Physi.js 是一个基于 Physijs 的物理引擎插件,用于为 Three.js 场景添加物理模拟(如碰撞检测、重力、刚体动力学等)。

1.1.1 ☘️代码示例

// 初始化 Physi.js 场景
const scene = new Physijs.Scene();// 创建带有物理效果的立方体
const box = new Physijs.BoxMesh(new THREE.BoxGeometry(1, 1, 1),new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
scene.add(box);// 监听碰撞事件
box.addEventListener('collision', (otherObject) => {console.log('发生碰撞!', otherObject);
});// 在动画循环中更新物理
function animate() {requestAnimationFrame(animate);scene.simulate(); // 更新物理模拟renderer.render(scene, camera);
}
animate();

1.1.2 ☘️核心方法/属性

Physijs.Scene
创建支持物理的 Three.js 场景。

mesh.setLinearVelocity()
设置物体的线性速度(移动速度)。

mesh.setAngularVelocity()
设置物体的角速度(旋转速度)。

mesh.addEventListener()
监听碰撞事件(如 ‘collision’)。

new Physijs.BoxMesh()
创建带有长方体碰撞体的物体。

new Physijs.SphereMesh()
创建带有球体碰撞体的物体。

scene.simulate()
在渲染循环中调用,更新物理模拟。

Physijs.createMaterial(material, friction, restitution)
创建物理材质,影响摩擦力和弹性。
参数:
material:Three.js 材质(如 THREE.MeshPhongMaterial)。
friction:摩擦系数(默认 0.8)。
restitution:弹性系数(默认 0)。

1.1.3 ☘️网格对象

Physijs.PlaneMesh // 这个网格可以用来创建一个厚度为0的平面。这样的平面也可以用BoxMesh对象包装一个高度很低的THREE.CubeGeometry来表示Physijs.BoxMesh // 如果是类似方块的几何体,你可以使用这个网格。例如,它的属性跟THREE.CubeGeometry的属性很相配Physijs.SphereMesh // 对于球形可以使用这个网格。它跟THREE.SphereGeometry的属性很相配Physijs.CylinderMesh // 通过设置THREE.Cylinder的属性你可以创建出各种柱状图形。Physijs为各种柱性提供了不同网格。Physijs.CylinderMesh可以用于一般的、上下一致的圆柱形Physijs.ConeMesh // 如果顶部的半径为0,底部的半径值大于0,那么你可以用THREE.Cylinder创建一个圆锥体。如果你想在这样一个对象上应用物理效果,那么可以使用的、最相匹配的网格类就是ConeMeshPhysijs.CapsuleMesh(胶囊网格) // 跟THREE.Cylinder属性很相似,但其底部和底部是圆的Physijs.ConvexMesh(凸包网格) // Physijs.ConvexMesh是一种比较粗略的图形,可用于多数复杂退行。它可以创建一个模拟复杂图形的凸包Physijs.ConcaveMesh // ConvexMesh是一个比较粗略的图形,而ConcaveMesh则可以对负责图形进行比较细致的表现。需要注意的是使用ConcaveMesh对效率的影响比较大Physijs.HeightfieldMesh(高度场网格) // 这是一种非常特别的网格。通过该网格你可以从一个THREE.PlaneGeometry对象创建出一个高度场。

1.1.4 ☘️约束

PointConstraint // 通过这个约束,你可以将一个对象与另一个对象之间的位置固定下来。例如一个对象动了,另一个对象也会随着移动,它们之间的距离和方向保持不变HingeConstraint // 通过活页约束,你可以限制一个对象只能像活页一样移动,例如门SliderConstraint // 将对象的移动限制在一个轴上。例如移门ConeTwistConstraint // 通过这个约束,你可以用一个对象限制另一个对象的旋转和移动。这个约束的功能类似于一个球削式关节。例如,胳膊在肩关节中的活动DOFConstraint // 通过自由度约束,你可以限制对象在任意轴上的活动,你可以设置对象活动的额最小、最大角度。这是最灵活的约束方式

1.1.4 ☘️约束、材质Materials、暂停/恢复模拟、场景配置、更新对象的位置和旋转使用样例

1.1.4.1 ☘️约束使用样例

点对点:

var constraint = new Physijs.PointConstraint(physijs_mesh_a, // 第一个被约束的对象physijs_mesh_b, // 限制第一个对象的物体,可以忽略,如果被忽略,第一个对象将被限制到点上new THREE.Vector3( 0, 10, 0 ) // 被限制到的点的位置
);
scene.addConstraint( constraint );

铰链约束:

var constraint = new Physijs.HingeConstraint(physijs_mesh_a, // 第一个被约束的对象physijs_mesh_b, // 限制第一个对象的物体,可以忽略,如果被忽略,第一个对象将被限制到点上new THREE.Vector3( 0, 10, 0 ), // 被限制到的点的位置new THREE.Vector3( 1, 0, 0 ) // 哪个轴向会被限制,当前默认是x轴
);
scene.addConstraint( constraint );
constraint.setLimits(low, // 最小运动角度,以弧度表示 high, // 最大运动角度,以弧度表示 bias_factor, // 设置误差范围relaxation_factor, // 控制极限反弹(0.0 ==不反弹) 
);
constraint.enableAngularMotor( target_velocity, acceration_force ); //可以设置力的方向(正方向或者负方向),当前的加速度
constraint.disableMotor(); //关闭当前的移动

滑块约束:

var constraint = new Physijs.SliderConstraint(physijs_mesh_a, // 被约束的对象physijs_mesh_b, // 限制第一个对象的物体,可以忽略,如果被忽略,第一个对象将被限制到点上new THREE.Vector3( 0, 10, 0 ), // 被限制到的点的位置new THREE.Vector3( 1, 0, 0 ) // 哪个轴向会被限制,当前默认是x轴
);
scene.addConstraint( constraint );
constraint.setLimits(linear_lower, // 线性移动的下限,以世界单位表示 linear_upper, // 线性移动的上限,以世界单位表示 angular_lower, // 角度移动的下限,以弧度表示 angular_upper // 角度上限运动,以弧度表示 
);
constraint.setRestitution(linear, // 达到线性限制时的恢复量angular // 达到角度限制时的恢复量
);
constraint.enableLinearMotor( target_velocity, acceration_force );//设置线性力的方向(正方向或者负方向),当前的加速度
constraint.disableLinearMotor();//关闭当前的线性移动
constraint.enableAngularMotor( target_velocity, acceration_force );//设置角旋转力的方向(正方向或者负方向),当前的加速度
constraint.disableAngularMotor();//关闭当前的旋转移动

锥形约束:

var constraint = new Physijs.ConeTwistConstraint(physijs_mesh_a, // 被约束的对象physijs_mesh_b, // 限制第一个对象的物体new THREE.Vector3( 0, 10, 0 ), // 被限制到的点的位置
);
scene.addConstraint( constraint );
constraint.setLimit( x, y, z ); // 每个轴限制的旋转限制,以弧度表示
constraint.setMotorMaxImpulse( max_impulse ); // 设置可以驱动第一个物体的力
constraint.setMotorTarget( target ); // target是约束的期望旋转,可以用THREE.Vector3,THREE.Matrix4或THREE.Quaternion
constraint.enableMotor(); //开启力
constraint.disableMotor(); //关闭力

自由度约束:

var constraint = new Physijs.DOFConstraint(physijs_mesh_a, // 被约束的对象physijs_mesh_b, // 限制第一个对象的物体new THREE.Vector3( 0, 10, 0 ), //  被限制到的点的位置
);
scene.addConstraint( constraint );
constraint.setLinearLowerLimit( new THREE.Vector3( -10, -5, 0 ) ); // 设置沿x,y和z轴的线性运动的下限
constraint.setLinearUpperLimit( new THREE.Vector3( 10, 5, 0 ) ); // 设置沿x,y和z轴线性运动的上限
constraint.setAngularLowerLimit( new THREE.Vector3( 0, -Math.PI, 0 ) ); // 沿着x,y和z轴以弧度设置角运动的下限
constraint.setAngularUpperLimit( new THREE.Vector3( 0, Math.PI, 0 ) ); // 沿着x,y和z轴以弧度设置角运动的上限
constraint.configureAngularMotor(which, // 指定马达工作的轴 0是x轴 1是y轴 2是z轴low_limit, // 设置马达的角度的下限high_limit, // 设置马达的角度的上限 下限设置的比上限高可以沿轴自由旋转velocity, // 目标速度max_force // 马达可以施加的最大力
);
constraint.enableAngularMotor( which ); // 开启哪个轴的马达0是x轴 1是y轴 2是z轴
constraint.disableAngularMotor( which ); // 关闭哪个轴的马达

冻结一个对象:
如果对象始终是静态的,例如地面,则可以0使用第三个参数创建网格时将其设置为质量:new Physijs.BoxMesh( geometry, material, 0)。任何具有质量的对象0将永远是静态的。

1.1.4.2 ☘️材质Materials使用样例

在THREE材质基础上增加了摩擦度和恢复度

var friction = 0.8; // 摩擦度
var restitution = 0.3; // 恢复度
var material = Physijs.createMaterial(new THREE.MeshBasicMaterial({ color: 0x888888 }),friction,restitution
);
var mesh = new Physijs.BoxMesh(new THREE.CubeGeometry( 5, 5, 5 ),material
);
1.1.4.3 ☘️暂停/恢复模拟使用样例
var render = function() {if (!isPaused) {scene.simulate();}renderer.render();
};
var unpauseSimulation = function() {isPaused = false;scene.onSimulationResume();
};

恢复模拟需要调用场景的onSimulationResume方法.

1.1.4.4 ☘️场景配置使用样例
  • fixedTimeStep default=1/60 此数字确定模拟步骤的模拟时间。数字越小,模拟越准确。
  • broadphase 指定将使用哪个宽带,选择是dynamic和sweepprune。
  • reportsize default 50 作为优化,包含对象位置的世界报告基于此数字预先初始化。最好将其设置为您的场景将具有的对象数量。
  • setGravity方法 default ( 0, -10, 0 ) 设定重力的数量和方向
  • setFixedTimeStep 在构造函数中default 1 / 60 重置fixedTimeStep给定的值
var scene = new Physijs.Scene({ reportsize: 50, fixedTimeStep: 1 / 60 });
1.1.4.5 ☘️更新对象的位置和旋转使用样例

有一个方面,无法与three.js进行无缝集成:更改对象的位置和/或旋转。如果这样做,您必须将该对象__dirtyPosition或__dirtyRotation标志设置为true,否则将从模拟中的最后一个已知值覆盖

var mesh = new Physijs.BoxMesh( geometry, material );
scene.add( mesh );var render = function() {// Change the object's positionmesh.position.set( 0, 0, 0 );mesh.__dirtyPosition = true;// Change the object's rotationmesh.rotation.set(0, 90, 180);mesh.__dirtyRotation = true;// You may also want to cancel the object's velocitymesh.setLinearVelocity(new THREE.Vector3(0, 0, 0));mesh.setAngularVelocity(new THREE.Vector3(0, 0, 0));scene.simulate();renderer.render();
};

二、🍀使用Physijs物理引擎,使用DOFConstraint自由度约束,模拟小车移动

1. ☘️实现思路

  • 1、引入‘physi.js’,创建Physijs物理引擎三维场景scene,设置scene场景重力信息。
  • 2、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt,场景scene添加camera。
  • 3、创建THREE.SpotLight聚光灯光源light,设置light位置,scene场景加入light。
  • 4、加载几何模型:定义createGround方法,使用‘floor-wood.jpg’木纹贴图创建地面网格对象ground以及四周突出边框网格对象borderLeft、borderRight、borderTop、borderBottom,ground添加borderLeft、borderRight、borderTop、borderBottom,调用createGround方法。定义createCar方法,用于生成受DOFConstraint自由度约束控制的小汽车,调用createCar获取car对象。定义controls方法,内部定义changeVelocity方法控制前轮的的重力影响,定义changeOrientation方法控制后轮的放松限制。调定义render方法,进行三维场景的渲染。具体代码参考下面代码样例。
  • 5、加入gui控制。加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html>
<head><style>body {margin: 0;overflow: hidden;background-color: #000000;}</style><title>学习threejs,使用Physijs物理引擎,使用DOFConstraint自由度约束,模拟小车移动</title><script type="text/javascript" src="../libs/three.js"></script><script type="text/javascript" src="../libs/stats.js"></script><script type="text/javascript" src="../libs/physi.js"></script><script type="text/javascript" src="../libs/dat.gui.js"></script><script type="text/javascript" src="../libs/chroma.js"></script><script type="text/javascript">'use strict';Physijs.scripts.worker = '../libs/physijs_worker.js';Physijs.scripts.ammo = '../libs/ammo.js';var scale = chroma.scale(['white', 'blue', 'red', 'yellow']);var initScene, render, applyForce, setMousePosition, mouse_position,ground_material, box_material,projector, renderer, render_stats, physics_stats, scene, ground, light, camera, box, boxes = [];initScene = function () {renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(window.innerWidth, window.innerHeight);renderer.setClearColor(new THREE.Color(0x000000));renderer.shadowMapEnabled = true;document.getElementById('viewport').appendChild(renderer.domElement);render_stats = new Stats();render_stats.domElement.style.position = 'absolute';render_stats.domElement.style.top = '1px';render_stats.domElement.style.left = '1px';render_stats.domElement.style.zIndex = 100;document.getElementById('viewport').appendChild(render_stats.domElement);scene = new Physijs.Scene({reportSize: 10, fixedTimeStep: 1 / 60});scene.setGravity(new THREE.Vector3(0, -40, 0));camera = new THREE.PerspectiveCamera(35,window.innerWidth / window.innerHeight,1,1000);camera.position.set(90, 90, 90);camera.lookAt(new THREE.Vector3(30, 0, -20));scene.add(camera);// 添加THREE.SpotLight聚光灯光源light,设置光源位置和投影信息light = new THREE.SpotLight(0xFFFFFF);light.position.set(120, 70, 100);light.castShadow = true;light.shadowMapDebug = true;light.shadowCameraNear = 10;light.shadowCameraFar = 200;scene.add(light);var meshes = [];// 创建木质地面createGround();var car = createCar();var controls = new function () {this.velocity = -2;this.wheelAngle = 0.5;this.loosenXRight = 0.0001;this.loosenXLeft = 0.0001;this.changeVelocity = function () {// 配置小汽车左右前轮z轴马达car.flConstraint.configureAngularMotor(2, 0.1, 0, controls.velocity, 15000);car.frConstraint.configureAngularMotor(2, 0.1, 0, controls.velocity, 15000);// motor one is for left and right// frConstraint.enableAngularMotor(1);// 启动前轮z轴马达car.flConstraint.enableAngularMotor(2);car.frConstraint.enableAngularMotor(2);};this.changeOrientation = function () {car.rrConstraint.setAngularLowerLimit({x: 0, y: controls.wheelAngle, z: 0.1});car.rrConstraint.setAngularUpperLimit({x: controls.loosenXRight, y: controls.wheelAngle, z: 0});car.rlConstraint.setAngularLowerLimit({x: controls.loosenXLeft, y: controls.wheelAngle, z: 0.1});car.rlConstraint.setAngularUpperLimit({x: 0, y: controls.wheelAngle, z: 0});}};var gui = new dat.GUI();gui.add(controls, 'velocity', -10, 10).onChange(controls.changeVelocity);gui.add(controls, 'wheelAngle', -1, 1).onChange(controls.changeOrientation);gui.add(controls, 'loosenXRight', 0, 0.5).step(0.01).onChange(controls.changeOrientation);gui.add(controls, 'loosenXLeft', 0, 0.6).step(-0.01).onChange(controls.changeOrientation);controls.loosenXLeft = 0;controls.loosenXRight = 0;requestAnimationFrame(render);scene.simulate();};function createWheel(position) {var wheel_material = Physijs.createMaterial(new THREE.MeshLambertMaterial({color: 0x444444, opacity: 0.9, transparent: true}),1.0, // high friction.5 // medium restitution);var wheel_geometry = new THREE.CylinderGeometry(4, 4, 2, 10);var wheel = new Physijs.CylinderMesh(wheel_geometry,wheel_material,100);wheel.rotation.x = Math.PI / 2;wheel.castShadow = true;wheel.position.copy(position);return wheel;}function createCar() {var car = {};var car_material = Physijs.createMaterial(new THREE.MeshLambertMaterial({color: 0xff4444, opacity: 0.9, transparent: true}),.5, // high friction.5 // medium restitution);// 创建小汽车身体var geom = new THREE.BoxGeometry(15, 4, 4);var body = new Physijs.BoxMesh(geom, car_material, 500);body.position.set(5, 5, 5);body.castShadow = true;scene.add(body);// 创建小汽车轮子var fr = createWheel(new THREE.Vector3(0, 4, 10));var fl = createWheel(new THREE.Vector3(0, 4, 0));var rr = createWheel(new THREE.Vector3(10, 4, 10));var rl = createWheel(new THREE.Vector3(10, 4, 0));// scene场景添加轮子scene.add(fr);scene.add(fl);scene.add(rr);scene.add(rl);var frConstraint = createWheelConstraint(fr, body, new THREE.Vector3(0, 4, 8));scene.addConstraint(frConstraint);var flConstraint = createWheelConstraint(fl, body, new THREE.Vector3(0, 4, 2));scene.addConstraint(flConstraint);var rrConstraint = createWheelConstraint(rr, body, new THREE.Vector3(10, 4, 8));scene.addConstraint(rrConstraint);var rlConstraint = createWheelConstraint(rl, body, new THREE.Vector3(10, 4, 2));scene.addConstraint(rlConstraint);// 后轮不能自行移动,在行驶过程中受到限制rrConstraint.setAngularLowerLimit({x: 0, y: 0.5, z: 0.1});rrConstraint.setAngularUpperLimit({x: 0, y: 0.5, z: 0});rlConstraint.setAngularLowerLimit({x: 0, y: 0.5, z: 0.1});rlConstraint.setAngularUpperLimit({x: 0, y: 0.5, z: 0});// 前轮只能沿z轴移动。frConstraint.setAngularLowerLimit({x: 0, y: 0, z: 0});frConstraint.setAngularUpperLimit({x: 0, y: 0, z: 0});flConstraint.setAngularLowerLimit({x: 0, y: 0, z: 0});flConstraint.setAngularUpperLimit({x: 0, y: 0, z: 0});//如果添加电机,则当前约束将被覆盖//如果你想旋转,把最小值设置得比最大值高flConstraint.configureAngularMotor(2, 0.1, 0, -2, 1500);frConstraint.configureAngularMotor(2, 0.1, 0, -2, 1500);// motor one is for left and right//frConstraint.enableAngularMotor(1);flConstraint.enableAngularMotor(2);frConstraint.enableAngularMotor(2);car.flConstraint = flConstraint;car.frConstraint = frConstraint;car.rlConstraint = rlConstraint;car.rrConstraint = rrConstraint;return car;}function createWheelConstraint(wheel, body, position) {var constraint = new Physijs.DOFConstraint(wheel, body, position);return constraint;}function createGround() {var length = 120;var width = 120;// Materialsground_material = Physijs.createMaterial(new THREE.MeshPhongMaterial({
//                                color: 0xaaaaaa,map: THREE.ImageUtils.loadTexture('../assets/textures/general/floor-wood.jpg')}),1, // high friction.7 // low restitution);ground = new Physijs.BoxMesh(new THREE.BoxGeometry(length, 1, width),ground_material,0 // mass);ground.receiveShadow = true;var borderLeft = new Physijs.BoxMesh(new THREE.BoxGeometry(2, 6, width),ground_material,0 // mass);borderLeft.position.x = -1 * length / 2 - 1;borderLeft.position.y = 2;borderLeft.receiveShadow = true;ground.add(borderLeft);var borderRight = new Physijs.BoxMesh(new THREE.BoxGeometry(2, 6, width),ground_material,0 // mass);borderRight.position.x = length / 2 + 1;borderRight.position.y = 2;borderRight.receiveShadow = true;ground.add(borderRight);var borderBottom = new Physijs.BoxMesh(new THREE.BoxGeometry(width - 1, 6, 2),ground_material,0 // mass);borderBottom.position.z = width / 2;borderBottom.position.y = 1.5;borderBottom.receiveShadow = true;ground.add(borderBottom);var borderTop = new Physijs.BoxMesh(new THREE.BoxGeometry(width, 6, 2),ground_material,0 // mass);borderTop.position.z = -width / 2;borderTop.position.y = 2;borderTop.receiveShadow = true;ground.position.x = 20;ground.position.z = -20;ground.add(borderTop);ground.receiveShadow = true;scene.add(ground);}render = function () {requestAnimationFrame(render);renderer.render(scene, camera);render_stats.update();scene.simulate(undefined, 2);};window.onload = initScene;</script>
</head><body>
<div id="viewport"></div>
</body></html>

效果如下:
在这里插入图片描述

相关文章:

学习threejs,使用Physijs物理引擎,使用DOFConstraint自由度约束,模拟小车移动

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️Physijs 物理引擎1.1.1 ☘️…...

仓颉开发语言入门教程:常见UI组件介绍和一些问题踩坑

幽蓝君发现一个问题&#xff0c;仓颉开发语言距离发布马上一年了&#xff0c;一些知名App已经使用仓颉开发了许多功能&#xff0c;但是网络上关于仓颉开发语言的教程少之又少&#xff0c;系统性的教程更是没有&#xff0c;仓颉官网的文档也远远不如ArkTS详尽。 现阶段对于想学…...

[Git] 初识 Git 与安装入门

告别文件噩梦&#xff1a;初识 Git 与安装入门 嘿&#xff0c;朋友&#xff01;不知道你是不是也遇到过这样的情况&#xff1a;你在写一份重要的文档、报告&#xff0c;或者更常见的&#xff0c;一段代码时&#xff0c;为了安全起见&#xff0c;怕改错了回不去&#xff0c;或者…...

海康威视摄像头C#开发指南:从SDK对接到安全增强与高并发优化

一、海康威视SDK核心对接流程​​ 1. ​​开发环境准备​​ ​​官方SDK获取​​&#xff1a;从海康开放平台下载最新版SDK&#xff08;如HCNetSDK.dll、PlayCtrl.dll&#xff09;。​​依赖项安装​​&#xff1a;确保C运行库&#xff08;如vcredist_x86.exe&#xff09;与S…...

大语言模型 14 - Manus 超强智能体 开源版本 OpenManus 上手指南

写在前面 Manus 是由中国初创公司 Monica.im 于 2025 年 3 月推出的全球首款通用型 AI 智能体&#xff08;AI Agent&#xff09;&#xff0c;旨在实现“知行合一”&#xff0c;即不仅具备强大的语言理解和推理能力&#xff0c;还能自主执行复杂任务&#xff0c;直接交付完整成…...

使用 LibreOffice 实现各种文档格式转换(支持任何开发语言调用 和 Linux + Windows 环境)[全网首发,保姆级教程,建议收藏]

以下能帮助你可以使用任何开发语言&#xff0c;在任何平台都能使用 LibreOffice 实现 Word、Excel、PPT 等文档的自动转换&#xff0c;目前展示在 ASP.NET Core 中为 PDF的实战案例&#xff0c;其他的文档格式转换逻辑同理。 &#x1f4e6; 1. 安装 LibreOffice &#x1f427;…...

CentOS Stream 9 中部署 MySQL 8.0 MGR(MySQL Group Replication)一主两从高可用集群

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《MySQL技术精粹》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、MySQL 8.0 中的高可用方案 2、适用场景 二、环境准备 1、系统环境说明…...

软考中级软件设计师——计算机网络篇

一、计算机网络体系结构 1.OSI七层模型 1. 物理层&#xff08;Physical Layer&#xff09; 功能&#xff1a;传输原始比特流&#xff08;0和1&#xff09;&#xff0c;定义物理介质&#xff08;如电缆、光纤&#xff09;的电气、机械特性。 关键设备&#xff1a;中继器&#…...

RK3568 OH5.1 源码编译及问题

安装编译器和二进制工具 在源码根目录下执行prebuilts脚本&#xff0c;安装编译器及二进制工具。 bash build/prebuilts_download.sh在源码根目录执行如下指令安装hb编译工具&#xff1a; python3 -m pip install --user build/hb使用build.sh脚本编译源码 进入源码根目录&…...

【razor】回环结构导致的控制信令错位:例如发送端收到 SR的问题

一、razor的echo程序 根据对 yuanrongxi/razor 仓库的代码和 echo 测试程序相关实现的分析,下面详细解读 echo 程序中 RTCP sender report(SR)、receiver report(RR)回显的问题及项目的解决方式。 1. 问题背景 在 RTP/RTCP 体系下,SR(Sender Report)由发送端周期性发…...

leetcode hot100:三、解题思路大全:哈希(两数之和、字母异位词分组、最长连续序列)、双指针(移动零、盛最多水的容器、三数之和、接雨水)

哈希 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按任意顺序返…...

MySQL 8.0 OCP 1Z0-908 161-170题

Q161.Examine this command, which executes successfully: cluster.addInstance ( ‘:’,{recoveryMethod: ‘clone’ 1}) Which three statements are true? (Choose three.) A)The account used to perform this recovery needs the BACKUP_ ADMIN privilege. B)A target i…...

onlyoffice 源码 调试说明 -ARM和x86双模式安装支持

很多用户在调试onlyoffice源码最大的问题是如何搭建环境,这个难度很高,下面提供一键安装的方式,让普通用户也能快速调试源码。 OnlyOffice Document Server 基于源码运行的容器调试模式&#xff0c;凭借 Docker 容器化技术的核心优势&#xff0c;为开发者提供了跨平台、高兼容性…...

workflow:高效的流式工作架构

引言 workflow是sougou的一款开源框架 主要是以请求回应的模式解决各自网络/IO任务而发明的 一.workflow的任务流 1.workflow都封装了哪些任务流 以请求回应的模式来解释 ① 网络层 服务端 在服务端的request 相当于发送了一个获取客户端请求的请求&#xff0c;response相当…...

音视频之H.265/HEVC速率控制

H.265/HEVC系列文章&#xff1a; 1、音视频之H.265/HEVC编码框架及编码视频格式 2、音视频之H.265码流分析及解析 3、音视频之H.265/HEVC预测编码 4、音视频之H.265/HEVC变换编码 5、音视频之H.265/HEVC量化 6、音视频之H.265/HEVC环路后处理 7、音视频之H.265/HEVC熵编…...

jsmpeg+java+ffmpeg 调用摄像头RTSP流播放

原理就是这样&#xff0c;明白吧。本次用springboot netty起这个2个服务&#xff0c;执行拉代码执行即可 <!-- netty --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.68.Final</ver…...

深度剖析ZooKeeper

1. ZooKeeper架构总览 ZooKeeper 是一个分布式协调服务&#xff0c;广泛用于分布式系统中的配置管理、命名服务、分布式锁和领导选举等场景。以下是对 ZooKeeper 架构、通信机制、容错处理、数据一致性与可靠性等方面的详细剖析。 一、ZooKeeper 主从集群 ZooKeeper 采用 主从…...

Zookeeper 集群安装与脚本化管理详解

安装之前:先关闭所有服务器的防火墙&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; systemctl stop firewalld 关闭防火墙 systemctl disable firewalld 开机不启动防火…...

第10天-Python操作MySQL数据库全攻略:从基础连接到高级应用

一、环境准备 1. 安装MySQL驱动 bash 复制 下载 # 官方推荐驱动 pip install mysql-connector-python# 或使用PyMySQL(兼容性更好) pip install pymysql 2. 创建测试数据库 sql 复制 下载 CREATE DATABASE python_db; USE python_db;CREATE TABLE users (id INT AU…...

Spring Cloud Gateway深度解析:原理、架构与生产实践

文章目录 前言一、概述二、核心架构设计及设计原理2.1 分层架构模型网络层&#xff08;I/O模型&#xff09;核心处理层 2.2 核心组件协作流程路由定位阶段过滤器执行阶段 2.3 响应式编程模型实现Reactor上下文传递背压处理机制 2.4 动态路由设计原理2.5 异常处理体系2.6 关键路…...

Trae 04.22版本深度解析:Agent能力升级与MCP市场对复杂任务执行的革新

我正在参加Trae「超级体验官」创意实践征文&#xff0c;本文所使用的 Trae 免费下载链接&#xff1a;Trae - AI 原生 IDE 目录 引言 一、Trae 04.22版本概览 二、统一对话体验的深度整合 2.1 Chat与Builder面板合并 2.2 统一对话的优势 三、上下文能力的显著增强 3.1 W…...

股指期货模型,简单易懂的套利策略

在股指期货投资领域&#xff0c;有不少实用的模型和策略&#xff0c;今天咱们就用大白话来唠唠其中几个重要的概念。 一、跨期套利&#xff1a;合约间的“差价游戏” 跨期套利简单来说&#xff0c;就是投资者以赚取期货合约之间的价差为目的&#xff0c;在同一个期货品种的不…...

MySQL 故障排查与生产环境优化

目录 1. MySQL单实例故障排查 2. MySQL 主从故障排查 3. MySQL 优化 3.1 硬件方面 3.2 MySQL 配置文件 3.3 SQL 方面 1. MySQL单实例故障排查 &#xff08;1&#xff09; 故障现象1 ERROR 2002 (HY000): Cant connect to local MySQL server through socket /data/mysql…...

Java泛型 的详细知识总结

一、泛型的核心作用 类型安全&#xff1a;在编译期检查类型匹配&#xff0c;避免运行时的ClassCastException。代码复用&#xff1a;通过泛型逻辑统一处理多种数据类型。消除强制转换&#xff1a;减少显式的类型转换代码。 二、泛型基础语法 1. 泛型类/接口 定义&#xff1a…...

k8s 配置 Kafka SASL_SSL双重认证

说明 kafka提供了多种安全认证机制&#xff0c;主要分为SASL和SSL两大类。 SASL&#xff1a; 是一种身份验证机制&#xff0c;用于在客户端和服务器之间进行身份验证的过程&#xff0c;其中SASL/PLAIN是基于账号密码的认证方式。 SSL&#xff1a; 是一种加密协议&#xff0c;…...

电商虚拟户:重构资金管理逻辑,解锁高效归集与智能分账新范式

一、电商虚拟户的底层架构与核心价值 在数字经济浪潮下&#xff0c;电商交易的复杂性与日俱增&#xff0c;传统账户体系已难以满足平台企业对资金管理的精细化需求。电商虚拟户作为基于银行或持牌支付机构账户体系的创新解决方案&#xff0c;通过构建“主账户子账户”的虚拟账户…...

从混乱到高效:我们是如何重构 iOS 上架流程的(含 Appuploader实践)

从混乱到高效&#xff1a;我们是如何重构 iOS 上架流程的 在开发团队中&#xff0c;有一类看不见却至关重要的问题&#xff1a;环境依赖。 特别是 iOS App 的发布流程&#xff0c;往往牢牢绑死在一台特定的 Mac 上。每次需要发版本&#xff0c;都要找到“那台 Mac”&#xff…...

01 基本介绍及Pod基础

01 查看各种资源 01-1 查看K8s集群的内置资源 [rootmaster01 ~]# kubectl api-resources NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 …...

DAY31-文件的规范拆分和写法

知识点回顾 规范的文件命名规范的文件夹管理机器学习项目的拆分编码格式和类型注解 &#xff08;一&#xff09;文件拆分 思考&#xff1a;如何把一个文件&#xff0c;拆分成多个具有着独立功能的文件&#xff0c;然后通过import的方式&#xff0c;来调用这些文件。这样具有几个…...

[创业之路-369]:企业战略管理案例分析-9-战略制定-差距分析的案例之华为

一、综合案例 在战略制定中&#xff0c;华为通过差距分析明确战略方向&#xff0c;以应对市场挑战和实现长期发展目标。 以下为具体案例与分析&#xff1a; 1、案例背景 华为在通信设备领域崛起过程中&#xff0c;始终将差距分析作为战略制定的核心环节。面对国际竞争对手&…...

【华为鸿蒙电脑】首款鸿蒙电脑发布:MateBook Fold 非凡大师 MateBook Pro,擎云星河计划启动

文章目录 前言一、HUAWEI MateBook Fold 非凡大师&#xff08;一&#xff09;非凡设计&#xff08;二&#xff09;非凡显示&#xff08;三&#xff09;非凡科技&#xff08;四&#xff09;非凡系统&#xff08;五&#xff09;非凡体验 二、HUAWEI MateBook Pro三、预热&#xf…...

深入理解Redis Cluster:架构、原理与实践

Redis 是一个高性能的键值存储数据库&#xff0c;广泛应用于缓存、会话存储、消息队列等场景。随着数据量和并发量的增长&#xff0c;单机 Redis 可能面临性能瓶颈和单点故障问题。为了解决这些问题&#xff0c;Redis 提供了 Redis Cluster&#xff0c;一种分布式解决方案&…...

分析 redis 的 exists 命令有一个参数和多个参数的区别

在 redis 中&#xff0c;exists 命令是用来查询某个或多个 key 是否存在的&#xff0c;返回存在的 key 的个数。 由于 redis 是按照键值对方式存储数据的&#xff0c;于是一个 key 只能对应一组数据&#xff0c;那么上述的 key 的个数指的即是需要查询的 key 中有几个 key 是存…...

[概率论基本概念1]什么是经验分布

一、说明 描述一个概率模型&#xff0c;有密度函数很好描述。如果写不出密度函数&#xff0c;退而用分布函数也能完整刻画&#xff0c;因此&#xff0c;分布函数表示比密度函数表示更加宽泛普适。本片讲述经验分布拟合分布函数的基础概念。 二、经验分布直观解释 在统计学中…...

使用Java实现Navicat密码的加密与解密

在日常开发过程中&#xff0c;我们有时需要处理各种软件保存的凭据信息&#xff0c;比如数据库连接密码等。这篇文章将介绍如何使用Java对Navicat保存的数据库密码进行加密和解密。 一、背景介绍 Navicat是一款强大的数据库管理工具&#xff0c;支持多种数据库系统。为了保护…...

怎么样进行定量分析

本文章将教会你如何对实验结果进行定量分析&#xff0c;其需要一定的论文基础&#xff0c;文末有论文撰写小技巧&#xff0c;不要看基础原理的人可以直接调到文章末尾。 一、什么是定量分析 定量分析是一种基于数据和数学模型的分析方法&#xff0c;它在众多领域中发挥着至关…...

python学习day2

今天主要学习了变量的数据类型&#xff0c;以及如何使用格式化符号进行输出。 一、认识数据类型 在python里为了应对不同的业务需求&#xff0c;也把数据分为不同的类型。 代码如下&#xff1a; """ 1、按类型将不同的变量存储在不同的类型数据 2、验证这些…...

FreeMarker

概述&#xff1a;FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据&#xff0c; 并用来生成输出文本(HTML网页&#xff0c;电子邮件&#xff0c;配置文件&#xff0c;源代码等)的通用工具。 它不是面向最终用户的&#xff0c;而是一个Java类库&#xff0c;是一款程序…...

JDK 21新特性详解

JDK 21新特性详解&#xff1a;现代Java开发的重大更新 Java开发工具包(JDK)21作为最新的长期支持(LTS)版本&#xff0c;于2023年9月发布&#xff0c;带来了许多令人兴奋的新特性。作为Java开发者&#xff0c;了解这些新功能对于保持技术竞争力至关重要。本文将详细介绍JDK 21中…...

使用MCP驱动IDA pro分析样本

最近国外的牛人开发了一个ida pro的mcp server&#xff0c;项目的地址为mrexodia/ida-pro-mcp: MCP Server for IDA Pro&#xff0c;实现了通过自然对话来分析样本。 今天我们试用一下。 MCP Server for IDA Pro项目简介 这个mcp server提供下面这些工具&#xff0c;基本涵盖…...

Web前端开发:@media(媒体查询)

什么是媒体查询&#xff1f; 媒体查询是CSS3的一个功能&#xff0c;允许你根据设备的特性&#xff08;如屏幕宽度、设备方向、分辨率等&#xff09;应用不同的CSS样式。简单来说&#xff0c;就是让网页在不同设备上&#xff08;手机、平板、电脑&#xff09;自动调整布局和样式…...

psotgresql18 源码编译安装

环境&#xff1a; 系统&#xff1a;centos7.9 数据库&#xff1a;postgresql18beta1 #PostgreSQL 18 已转向 DocBook XML 构建体系&#xff08;SGML 未来将被弃用&#xff09;。需要安装 XML 工具链&#xff0c;如下&#xff1a; yum install -y docbook5-style-xsl libxsl…...

如何在VSCode中更换默认浏览器:完整指南

引言 作为前端开发者&#xff0c;我们经常需要在VSCode中快速预览HTML文件。默认情况下&#xff0c;VSCode会使用系统默认浏览器打开文件&#xff0c;但有时我们可能需要切换到其他浏览器进行测试。本文将详细介绍如何在VSCode中更换默认浏览器。 方法一&#xff1a;使用VSCo…...

Python Day26 学习

继续NumPy的学习 数组的索引 一维数组的索引 创建及输出 arr1d np.arange(10) # 数组: [0 1 2 3 4 5 6 7 8 9] arr1d array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 取出数组的第一个元素&#xff0c;最后一个元素 代码实现 arr1d[0] arr1d[-1] 取出数组中索引为3&#x…...

2025年PMP 学习二十一 14章 项目立项管理

2025年PMP 学习二十一 14章 项目立项管理 项目立项管理 项目建议 (Project Proposal)项目可行性分析 (Project Feasibility Analysis)项目审批 (Project Approval)项目招投标 (Project Tendering)项目合同谈判和签订 (Project Contract Negotiation and Signing) 文章目录 20…...

Ubuntu开机自启服务

一、准备启动脚本 在你的项目文件夹&#xff08;例如 /home/ubuntu/Plant_Diease_Recongnization_Server_1&#xff09;中创建一个启动脚本 run_ui_main.sh&#xff1a; #!/usr/bin/env bash # run_ui_main.sh&#xff1a;激活 yolov8 环境并启动 ui_main.py# 设置 Anaconda/…...

使用Docker部署React应用与Nginx

这个教程将帮助您使用Docker部署一个带有React的Nginx容器&#xff0c;并通过卷(volumes)将本地代码绑定到Docker容器中。这种设置非常适合开发环境&#xff0c;因为它允许您在本地编辑代码&#xff0c;而容器中的应用会自动更新。 步骤概述 创建Nginx配置文件创建Dockerfile…...

基于SpringBoot的小型民营加油站管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

Triton介绍和各平台支持情况分析

文章目录 &#x1f49e;Triton介绍&#x1f9e0; Triton 是什么&#xff1f;&#x1f50d; Triton 的核心特点&#x1f680; Triton 在 PyTorch 中的作用&#x1f4e6; Triton 的典型使用场景&#x1f9ea; 示例&#xff1a;Triton 编写的向量加法&#xff08;GPU 并行&#xf…...

HTTPS核心机制拆解

目录 引言 HTTPS和HTTP的区别 常见加密方式 数据摘要 数字证书与数据签名 HTTPS请求过程 结语 引言 HTTPS是什么&#xff1f;是一个应用层协议&#xff0c;在HTTP协议的基础上引入了一层加密层。为什么需要HTTPS&#xff1f;答案是显而易见的&#xff0c;要加密&#xf…...