btSoftRigidDynamicsWorld 类是 Ammo.js 物理库中的一个类,表示一个动态世界,用于处理软体和刚体物体的物理模拟。

demo案例
在这里插入图片描述

btSoftRigidDynamicsWorld 类是 Ammo.js 物理库中的一个类,表示一个动态世界,用于处理软体和刚体物体的物理模拟。让我们按照输入参数、输出、属性和方法来详细解释其 API:

输入参数:

  1. dispatcher:这是一个 btCollisionDispatcher 实例,负责分派碰撞检测和处理。
  2. broadphase:一个 btBroadphaseInterface 实例,用于广义相交检测,例如高效地识别潜在的碰撞对。
  3. solver:一个 btConstraintSolver 实例,负责解决刚体和软体之间的约束。
  4. collisionConfiguration:一个 btCollisionConfiguration 实例,配置碰撞检测算法的行为。
  5. softBodySolver:一个 btSoftBodySolver 实例,负责解决软体物理模拟。

输出:

一个 btSoftRigidDynamicsWorld 实例,代表着模拟软体和刚体物理的动态世界。

属性:

  • 重力(Gravity):表示作用于世界中物体的重力。
  • 世界信息(World Info):世界的配置信息,如重力和模拟参数等。

方法:

  1. addSoftBody(softBody, collisionFilterGroup, collisionFilterMask):将软体添加到世界中进行模拟。collisionFilterGroupcollisionFilterMask 参数确定软体属于哪些碰撞组,并且与哪些碰撞组进行交互。

  2. removeSoftBody(softBody):从世界中移除软体。

  3. addRigidBody(rigidBody, collisionFilterGroup, collisionFilterMask):将刚体添加到世界中进行模拟。collisionFilterGroupcollisionFilterMask 参数确定刚体属于哪些碰撞组,并且与哪些碰撞组进行交互。

  4. removeRigidBody(rigidBody):从世界中移除刚体。

  5. setGravity(gravityVector):设置作用于世界中物体的重力。

  6. stepSimulation(deltaTime, maxSubSteps, fixedTimeStep):按照指定的时间步长 (deltaTime) 推进模拟。maxSubSteps 确定要执行的最大子步数,fixedTimeStep 指定模拟的固定时间步长。

  7. getGravity():获取当前作用于世界中物体的重力。

  8. getWorldInfo():获取包含世界配置设置的世界信息对象。

  9. getSoftBodyArray():获取当前世界中所有软体的数组。

  10. getRigidBodyArray():获取当前世界中所有刚体的数组。

  11. setInternalTickCallback(callback, worldUserInfo):设置在每个模拟步骤期间内部调用的回调函数。这可用于自定义处理或调试目的。

  12. setWorldUserInfo(worldUserInfo):设置与世界关联的用户定义信息。

  13. getWorldUserInfo():获取与世界关联的用户定义信息。

这些方法允许您操纵和控制动态世界,添加和移除对象,设置重力,推进模拟,并获取有关世界及其内容的信息。

demo 源码

<html lang="en"><head><title>Ammo.js softbody cloth demo</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"><link type="text/css" rel="stylesheet" href="main.css"><style>body {color: #333;}</style></head><body><div id="info">Ammo.js physics soft body cloth demo<br>Press Q or A to move the arm.</div> <!-- 显示提示信息 --><div id="container"></div> <!-- 用于渲染 Three.js 场景 --><script src="jsm/libs/ammo.wasm.js"></script> <!-- 引入 Ammo.js 的 WASM 文件 --><script type="importmap">{"imports": {"three": "../build/three.module.js", <!-- 导入 Three.js -->"three/addons/": "./jsm/" <!-- 导入 Three.js 的附加模块 -->}}</script><script type="module">import * as THREE from 'three'; <!-- 导入 Three.js 库 -->import Stats from 'three/addons/libs/stats.module.js'; <!-- 导入性能统计模块 -->import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; <!-- 导入 OrbitControls 控制器 -->// Graphics variableslet container, stats; <!-- 定义图形相关的变量 -->let camera, controls, scene, renderer; <!-- 定义相机、控制器、场景、渲染器 -->let textureLoader; <!-- 定义纹理加载器 -->const clock = new THREE.Clock(); <!-- 创建时钟对象 -->// Physics variablesconst gravityConstant = - 9.8; <!-- 定义重力常数 -->let physicsWorld; <!-- 定义物理世界对象 -->const rigidBodies = []; <!-- 用于存储刚体的数组 -->const margin = 0.05; <!-- 定义边距 -->let hinge; <!-- 定义铰链约束对象 -->let cloth; <!-- 定义布料对象 -->let transformAux1; <!-- 定义辅助变换对象 -->let armMovement = 0; <!-- 定义臂的移动量,默认为0 -->Ammo().then( function ( AmmoLib ) { <!-- 异步加载 Ammo.js 库并初始化 -->Ammo = AmmoLib;init(); <!-- 调用初始化函数 -->animate(); <!-- 调用动画函数 -->} );function init() {initGraphics(); <!-- 初始化图形相关设置 -->initPhysics(); <!-- 初始化物理相关设置 -->createObjects(); <!-- 创建物体对象 -->initInput(); <!-- 初始化输入监听 -->}function initGraphics() {container = document.getElementById( 'container' ); <!-- 获取容器元素 -->camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.2, 2000 ); <!-- 创建透视相机 -->scene = new THREE.Scene(); <!-- 创建场景 -->scene.background = new THREE.Color( 0xbfd1e5 ); <!-- 设置场景背景色 -->camera.position.set( - 12, 7, 4 ); <!-- 设置相机位置 -->renderer = new THREE.WebGLRenderer( { antialias: true } ); <!-- 创建 WebGL 渲染器 -->renderer.setPixelRatio( window.devicePixelRatio ); <!-- 设置像素比例 -->renderer.setSize( window.innerWidth, window.innerHeight ); <!-- 设置渲染器尺寸 -->renderer.shadowMap.enabled = true; <!-- 启用阴影 -->container.appendChild( renderer.domElement ); <!-- 将渲染器元素添加到容器中 -->controls = new OrbitControls( camera, renderer.domElement ); <!-- 创建轨道控制器 -->controls.target.set( 0, 2, 0 ); <!-- 设置控制器焦点 -->controls.update(); <!-- 更新控制器 -->textureLoader = new THREE.TextureLoader(); <!-- 创建纹理加载器 -->const ambientLight = new THREE.AmbientLight( 0xbbbbbb ); <!-- 创建环境光 -->scene.add( ambientLight ); <!-- 将环境光添加到场景中 -->const light = new THREE.DirectionalLight( 0xffffff, 3 ); <!-- 创建平行光 -->light.position.set( - 7, 10, 15 ); <!-- 设置光源位置 -->light.castShadow = true; <!-- 启用阴影 -->const d = 10;light.shadow.camera.left = - d; <!-- 设置阴影相机左边界 -->light.shadow.camera.right = d; <!-- 设置阴影相机右边界 -->light.shadow.camera.top = d; <!-- 设置阴影相机上边界 -->light.shadow.camera.bottom = - d; <!-- 设置阴影相机下边界 -->light.shadow.camera.near = 2; <!-- 设置阴影相机近裁剪面 -->light.shadow.camera.far = 50; <!-- 设置阴影相机远裁剪面 -->light.shadow.mapSize.x = 1024; <!-- 设置阴影贴图宽度 -->light.shadow.mapSize.y = 1024; <!-- 设置阴影贴图高度 -->light.shadow.bias = - 0.003; <!-- 设置阴影偏移 -->scene.add( light ); <!-- 将平行光添加到场景中 -->stats = new Stats(); <!-- 创建性能统计器 -->stats.domElement.style.position = 'absolute'; <!-- 设置性能统计器位置样式 -->stats.domElement.style.top = '0px'; <!-- 设置性能统计器顶部样式 -->container.appendChild( stats.domElement ); <!-- 将性能统计器元素添加到容器中 -->window.addEventListener( 'resize', onWindowResize ); <!-- 监听窗口大小变化事件 -->}function initPhysics() {// Physics configurationconst collisionConfiguration = new Ammo.btSoftBodyRigidBodyCollisionConfiguration(); <!-- 创建碰撞配置对象 -->const dispatcher = new Ammo.btCollisionDispatcher( collisionConfiguration ); <!-- 创建碰撞调度器对象 -->const broadphase = new Ammo.btDbvtBroadphase(); <!-- 创建宽相对象 -->const solver = new Ammo.btSequentialImpulseConstraintSolver(); <!-- 创建顺序脉冲约束求解器对象 -->const softBodySolver = new Ammo.btDefaultSoftBodySolver(); <!-- 创建默认软体求解器对象 -->physicsWorld = new Ammo.btSoftRigidDynamicsWorld( dispatcher, broadphase, solver, collisionConfiguration, softBodySolver ); <!-- 创建软刚体动力学世界对象 -->physicsWorld.setGravity( new Ammo.btVector3( 0, gravityConstant, 0 ) ); <!-- 设置重力 -->physicsWorld.getWorldInfo().set_m_gravity( new Ammo.btVector3( 0, gravityConstant, 0 ) ); <!-- 设置世界重力 -->transformAux1 = new Ammo.btTransform(); <!-- 创建辅助变换对象 -->}function createObjects() {const pos = new THREE.Vector3(); <!-- 创建位置向量 -->const quat = new THREE.Quaternion(); <!-- 创建四元数对象 -->// Groundpos.set( 0, - 0.5, 0 ); <!-- 设置地面位置 -->quat.set( 0, 0, 0, 1 ); <!-- 设置地面四元数 -->const ground = createParalellepiped( 40, 1, 40, 0, pos, quat, new THREE.MeshPhongMaterial( { color: 0xFFFFFF } ) ); <!-- 创建地面 -->ground.castShadow = true; <!-- 启用地面阴影 -->ground.receiveShadow = true; <!-- 启用地面接收阴影 -->textureLoader.load( 'textures/grid.png', function ( texture ) { <!-- 加载纹理 -->texture.colorSpace = THREE.SRGBColorSpace; <!-- 设置纹理颜色空间 -->texture.wrapS = THREE.RepeatWrapping; <!-- 设置纹理水平重复方式 -->texture.wrapT = THREE.RepeatWrapping; <!-- 设置纹理垂直重复方式 -->texture.repeat.set( 40, 40 ); <!-- 设置纹理重复次数 -->ground.material.map = texture; <!-- 设置地面纹理 -->ground.material.needsUpdate = true;} );// Wallconst brickMass = 0.5; <!-- 设置砖块质量 -->const brickLength = 1.2; <!-- 设置砖块长度 -->const brickDepth = 0.6; <!-- 设置砖块深度 -->const brickHeight = brickLength * 0.5; <!-- 计算砖块高度 -->const numBricksLength = 6; <!-- 设置砖块长度数量 -->const numBricksHeight = 8; <!-- 设置砖块高度数量 -->const z0 = - numBricksLength * brickLength * 0.5; <!-- 计算初始位置 -->pos.set( 0, brickHeight * 0.5, z0 ); <!-- 设置初始位置 -->quat.set( 0, 0, 0, 1 ); <!-- 设置初始四元数 -->for ( let j = 0; j < numBricksHeight; j ++ ) { <!-- 创建砖块墙 -->const oddRow = ( j % 2 ) == 1;pos.z = z0;if ( oddRow ) {pos.z -= 0.25 * brickLength;}const nRow = oddRow ? numBricksLength + 1 : numBricksLength;for ( let i = 0; i < nRow; i ++ ) {let brickLengthCurrent = brickLength;let brickMassCurrent = brickMass;if ( oddRow && ( i == 0 || i == nRow - 1 ) ) {brickLengthCurrent *= 0.5;brickMassCurrent *= 0.5;}const brick = createParalellepiped( brickDepth, brickHeight, brickLengthCurrent, brickMassCurrent, pos, quat, createMaterial() );brick.castShadow = true;brick.receiveShadow = true;if ( oddRow && ( i == 0 || i == nRow - 2 ) ) {pos.z += 0.75 * brickLength;} else {pos.z += brickLength;}}pos.y += brickHeight;}// The cloth// Cloth graphic objectconst clothWidth = 4; <!-- 设置布料宽度 -->const clothHeight = 3; <!-- 设置布料高度 -->const clothNumSegmentsZ = clothWidth * 5; <!-- 设置布料 Z 轴分段数 -->const clothNumSegmentsY = clothHeight * 5; <!-- 设置布料 Y 轴分段数 -->const clothPos = new THREE.Vector3( - 3, 3, 2 ); <!-- 设置布料位置 -->const clothGeometry = new THREE.PlaneGeometry( clothWidth, clothHeight, clothNumSegmentsZ, clothNumSegmentsY ); <!-- 创建布料几何体 -->clothGeometry.rotateY( Math.PI * 0.5 ); <!-- 旋转布料几何体 -->clothGeometry.translate( clothPos.x, clothPos.y + clothHeight * 0.5, clothPos.z - clothWidth * 0.5 ); <!-- 平移布料几何体 -->const clothMaterial = new THREE.MeshLambertMaterial( { color: 0xFFFFFF, side: THREE.DoubleSide } ); <!-- 创建布料材质 -->cloth = new THREE.Mesh( clothGeometry, clothMaterial ); <!-- 创建布料对象 -->cloth.castShadow = true; <!-- 启用布料阴影 -->cloth.receiveShadow = true; <!-- 启用布料接收阴影 -->scene.add( cloth ); <!-- 将布料添加到场景中 -->textureLoader.load( 'textures/grid.png', function ( texture ) { <!-- 加载纹理 -->texture.colorSpace = THREE.SRGBColorSpace; <!-- 设置纹理颜色空间 -->texture.wrapS = THREE.RepeatWrapping; <!-- 设置纹理水平重复方式 -->texture.wrapT = THREE.RepeatWrapping; <!-- 设置纹理垂直重复方式 -->texture.repeat.set( clothNumSegmentsZ, clothNumSegmentsY ); <!-- 设置纹理重复次数 -->cloth.material.map = texture; <!-- 设置布料纹理 -->cloth.material.needsUpdate = true;} );// Cloth physic objectconst softBodyHelpers = new Ammo.btSoftBodyHelpers(); <!-- 创建软体助手对象 -->const clothCorner00 = new Ammo.btVector3( clothPos.x, clothPos.y + clothHeight, clothPos.z ); <!-- 设置布料顶点位置 -->const clothCorner01 = new Ammo.btVector3( clothPos.x, clothPos.y + clothHeight, clothPos.z - clothWidth ); <!-- 设置布料顶点位置 -->const clothCorner10 = new Ammo.btVector3( clothPos.x, clothPos.y, clothPos.z ); <!-- 设置布料顶点位置 -->const clothCorner11 = new Ammo.btVector3( clothPos.x, clothPos.y, clothPos.z - clothWidth ); <!-- 设置布料顶点位置 -->const clothSoftBody = softBodyHelpers.CreatePatch( physicsWorld.getWorldInfo(), clothCorner00, clothCorner01, clothCorner10, clothCorner11, clothNumSegmentsZ + 1, clothNumSegmentsY + 1, 0, true ); <!-- 创建布料软体对象 -->const sbConfig = clothSoftBody.get_m_cfg(); <!-- 获取软体配置对象 -->sbConfig.set_viterations( 10 ); <!-- 设置速度迭代次数 -->sbConfig.set_piterations( 10 ); <!-- 设置位置迭代次数 -->clothSoftBody.setTotalMass( 0.9, false ); <!-- 设置总质量 -->Ammo.castObject( clothSoftBody, Ammo.btCollisionObject ).getCollisionShape().setMargin( margin * 3 ); <!-- 设置碰撞形状边距 -->physicsWorld.addSoftBody( clothSoftBody, 1, - 1 ); <!-- 将布料软体添加到物理世界 -->cloth.userData.physicsBody = clothSoftBody; <!-- 将物理软体对象存储在布料对象的自定义数据中 -->// Disable deactivationclothSoftBody.setActivationState( 4 ); <!-- 禁用物理软体的休眠状态 -->// The baseconst armMass = 2; <!-- 设置臂的质量 -->const armLength = 3 + clothWidth; <!-- 计算臂的长度 -->const pylonHeight = clothPos.y + clothHeight; <!-- 计算支柱高度 -->const baseMaterial = new THREE.MeshPhongMaterial( { color: 0x606060 } ); <!-- 创建基座材质 -->pos.set( clothPos.x, 0.1, clothPos.z - armLength ); <!-- 设置基座位置 -->quat.set( 0, 0, 0, 1 ); <!-- 设置基座四元数 -->const base = createParalellepiped( 1, 0.2, 1, 0, pos, quat, baseMaterial ); <!-- 创建基座 -->base.castShadow = true; <!-- 启用基座阴影 -->base.receiveShadow = true; <!-- 启用基座接收阴影 -->pos.set( clothPos.x, 0.5 * pylonHeight, clothPos.z - armLength ); <!-- 设置支柱位置 -->const pylon = createParalellepiped( 0.4, pylonHeight, 0.4, 0, pos, quat, baseMaterial ); <!-- 创建支柱 -->pylon.castShadow = true; <!-- 启用支柱阴影 -->pylon.receiveShadow = true; <!-- 启用支柱接收阴影 -->pos.set( clothPos.x, pylonHeight + 0.2, clothPos.z - 0.5 * armLength ); <!-- 设置臂位置 -->const arm = createParalellepiped( 0.4, 0.4, armLength + 0.4, armMass, pos, quat, baseMaterial ); <!-- 创建臂 -->arm.castShadow = true; <!-- 启用臂阴影 -->arm.receiveShadow = true; <!-- 启用臂接收阴影 -->// Glue the cloth to the armconst influence = 0.5; <!-- 设置影响因子 -->clothSoftBody.appendAnchor( 0, arm.userData.physicsBody, false, influence ); <!-- 添加布料到臂的锚点 -->clothSoftBody.appendAnchor( clothNumSegmentsZ, arm.userData.physicsBody, false, influence ); <!-- 添加布料到臂的锚点 -->// Hinge constraint to move the armconst pivotA = new Ammo.btVector3( 0, pylonHeight * 0.5, 0 ); <!-- 设置铰链约束 A 点位置 -->const pivotB = new Ammo.btVector3( 0, - 0.2, - armLength * 0.5 ); <!-- 设置铰链约束 B 点位置 -->const axis = new Ammo.btVector3( 0, 1, 0 ); <!-- 设置铰链约束轴向 -->hinge = new Ammo.btHingeConstraint( pylon.userData.physicsBody, arm.userData.physicsBody, pivotA, pivotB, axis, axis, true ); <!-- 创建铰链约束对象 -->physicsWorld.addConstraint( hinge, true ); <!-- 将铰链约束添加到物理世界 -->}function createParalellepiped( sx, sy, sz, mass, pos, quat, material ) {const threeObject = new THREE.Mesh( new THREE.BoxGeometry( sx, sy, sz, 1, 1, 1 ), material ); <!-- 创建立方体网格对象 -->const shape = new Ammo.btBoxShape( new Ammo.btVector3( sx * 0.5, sy * 0.5, sz * 0.5 ) ); <!-- 创建立方体碰撞形状 -->shape.setMargin( margin ); <!-- 设置碰撞形状边距 -->createRigidBody( threeObject, shape, mass, pos, quat ); <!-- 创建刚体对象 */return threeObject;}function createRigidBody( threeObject, physicsShape, mass, pos, quat ) {threeObject.position.copy( pos ); <!-- 复制位置 */threeObject.quaternion.copy( quat); <!-- 复制四元数 */const transform = new Ammo.btTransform(); <!-- 创建变换对象 */transform.setIdentity(); <!-- 初始化变换对象 */transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) ); <!-- 设置变换对象的位置 */transform.setRotation( new Ammo.btQuaternion( quat.x, quat.y, quat.z, quat.w ) ); <!-- 设置变换对象的旋转 */const motionState = new Ammo.btDefaultMotionState( transform ); <!-- 创建默认运动状态 */const localInertia = new Ammo.btVector3( 0, 0, 0 ); <!-- 创建局部惯性矩阵 */physicsShape.calculateLocalInertia( mass, localInertia ); <!-- 计算局部惯性矩阵 */const rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, physicsShape, localInertia ); <!-- 创建刚体信息对象 */const body = new Ammo.btRigidBody( rbInfo ); <!-- 创建刚体对象 */threeObject.userData.physicsBody = body; <!-- 存储刚体对象到网格对象的自定义数据中 */scene.add( threeObject ); <!-- 将网格对象添加到场景中 */if ( mass > 0 ) {rigidBodies.push( threeObject ); <!-- 如果质量大于0,将网格对象添加到刚体数组中 */// Disable deactivationbody.setActivationState( 4 ); <!-- 禁用休眠状态 */}physicsWorld.addRigidBody( body ); <!-- 将刚体添加到物理世界中 */return body;}function initInput() {window.addEventListener( 'keydown', function ( event ) { <!-- 监听按键事件 */switch ( event.keyCode ) { <!-- 根据按键码执行不同操作 */case 81: // Q <!-- 按 Q 键,左移臂 -->armMovement = 1;break;case 65: // A <!-- 按 A 键,右移臂 */armMovement = - 1;break;}} );window.addEventListener( 'keyup', function ( event ) { <!-- 监听松开按键事件 */switch ( event.keyCode ) { <!-- 根据按键码执行不同操作 */case 81: // Q <!-- 松开 Q 键,停止臂的移动 */case 65: // A <!-- 松开 A 键,停止臂的移动 */armMovement = 0;break;}} );}function animate() {requestAnimationFrame( animate ); <!-- 请求动画帧 */const deltaTime = clock.getDelta(); <!-- 获取两帧之间的时间差 */if ( deltaTime > 0 ) {updatePhysics( deltaTime ); <!-- 更新物理 */updateArmMovement(); <!-- 更新臂的移动 */}render(); <!-- 渲染场景 */stats.update(); <!-- 更新性能统计器 */}function updatePhysics( deltaTime ) {// Step worldphysicsWorld.stepSimulation( deltaTime, 10 ); <!-- 更新物理世界 */// Update clothconst softBody = cloth.userData.physicsBody; <!-- 获取布料软体对象 */const clothPositions = cloth.geometry.attributes.position.array; <!-- 获取布料几何体的位置数组 */const numVerts = clothPositions.length / 3; <!-- 获取布料顶点数量 */const nodes = softBody.get_m_nodes(); <!-- 获取布料软体的节点对象 */for ( let i = 0; i < numVerts; i ++ ) {const node = nodes.at( i ); <!-- 获取当前节点 */const nodePos = node.get_m_x(); <!-- 获取当前节点的位置 */clothPositions[ i * 3 ] = nodePos.x(); <!-- 更新布料顶点位置 */clothPositions[ i * 3 + 1 ] = nodePos.y(); <!-- 更新布料顶点位置 */clothPositions[ i * 3 + 2 ] = nodePos.z(); <!-- 更新布料顶点位置 */}cloth.geometry.attributes.position.needsUpdate = true; <!-- 标记位置属性需要更新 */}function updateArmMovement() {if ( armMovement !== 0 ) { <!-- 如果臂的移动量不为0 */const hingeConstraint = hinge; <!-- 获取铰链约束对象 */const angle = hingeConstraint.getHingeAngle(); <!-- 获取铰链约束角度 */const targetAngle = angle + armMovement * 0.05; <!-- 计算目标角度 */hingeConstraint.enableAngularMotor( true, 1.5, 50 ); <!-- 启用角动力器 */hingeConstraint.setMotorTarget( targetAngle, 0.8 ); <!-- 设置角动力器目标角度 */hingeConstraint.setMaxMotorImpulse( 0.8 ); <!-- 设置角动力器最大冲量 */} else { <!-- 如果臂的移动量为0 */hinge.enableAngularMotor( false, 0, 0 ); <!-- 禁用角动力器 */}}function render() {renderer.render( scene, camera ); <!-- 渲染场景 */}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight; <!-- 更新相机宽高比 */camera.updateProjectionMatrix(); <!-- 更新投影矩阵 */renderer.setSize( window.innerWidth, window.innerHeight ); <!-- 更新渲染器尺寸 */}</script></body>
</html>

本内容来源于小豆包,想要更多内容请跳转小豆包 》

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一天300收入打底,​一个适合任何人的创业项目!

共享旅游卡项目&#xff0c;一天300收入打底&#xff0c;一个适合任何人的创业项目&#xff01; 只要你不懒&#xff0c;生活总过得不会太差。只要你不贪&#xff0c;就算不能大富大贵&#xff0c;至少不会负债累累。 人性最难戒掉的两个字&#xff1a;一个是懒&#xff0c;另…

理解 编译和链接

目录 1. 翻译环境和运行环境 2. 翻译环境 2.1 预处理&#xff08;预编译&#xff09; 2.2 编译 2.2.1 词法分析&#xff1a; 2.2.2 语法分析 2.2.3 语义分析 2.3 汇编 2.4 链接 3. 运行环境 1. 翻译环境和运行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同…

Hystrix:实现分布式系统的延迟处理和容错保护机制

文章目录 一、Hystrix的概念与作用1.1、资源隔离1.2、熔断器模式1.3、命令模式1.4、监控和报警 二、Hystrix的使用方法三、总结 一、Hystrix的概念与作用 Hystrix是Netflix开源的一个库&#xff0c;用于处理分布式系统中的延迟和容错。它通过在服务调用之间添加保护机制&#…

分享5个好用的ChatGPT

目录 1、ChatGPT Web (cnote.top) 2、Gnomic智能体平台|AI Agent|CarrotAI大模型 3、Ymiai-快捷、高效的人工智能创作平台 4、chatAI中文版 5、智能助手 1、ChatGPT Web (cnote.top) https://f1.cnote.top/#/chat/1002 2、 Gnomic智能体平台|AI Agent|CarrotAI大模型 https:/…

五、书架开发--1.书架标题组件交互、获取书架数据

添加书架页面&#xff0c;做路由配置 首先添加书架页面&#xff0c;到views中的store中添加一个StoreShelf表示书架 然后到路由中进行注册 然后书城首页的返回键我们是想要点击返回的话就跳转到书架页面&#xff0c;所以如下this.$router.push(/store/shelf) 做书架标题组件 …

MySQL数据库的详解(1)

DDL&#xff08;数据库操作&#xff09; 查询 查询所有数据库&#xff1a;show databases;当前数据库&#xff1a;select database(); 创建 创建数据库&#xff1a;create database [ if not exists] 数据库名 ; 使用 使用数据库&#xff1a;use 数据库名 ; 删除 删除数…

事务的隔离性

参考: 小林coding MySQL服务器同时处理多个事务时&#xff0c;会出现脏读&#xff0c;不可重复读&#xff0c;幻读问题。 脏读 一个事务读到另一个未提交事务修改过的数据。 举例&#xff1a;事务A先读取数据&#xff0c;并对其进行修改&#xff0c;此时事务B进行读取获取到…

如何做好谷歌广告投放?谷歌广告投放要点解析

市场是在不断变化的&#xff0c;搜索引擎上的网站排名也随着市场的变化而变化。如果你的广告战术一成不变&#xff0c;很容易花冤枉钱。从本质上来讲&#xff0c;谷歌广告的优化工作就是让商家在搜索引擎上保持长久的市场竞争力。 如果商家不经常优化Google广告&#xff0c;可能…

深入理解MD5算法:原理、应用与安全

title: 深入理解MD5算法&#xff1a;原理、应用与安全 date: 2024/4/11 20:55:57 updated: 2024/4/11 20:55:57 tags: MD5算法数据安全哈希函数摘要算法安全漏洞SHA算法密码学 第一章&#xff1a;引言 导言 在当今数字化时代&#xff0c;数据安全和完整性变得至关重要。消息…

[Kubernetes[K8S]集群:master主节点初始化]:通过Calico和Coredns网络插件方式安装

文章目录 操作流程&#xff1a;前置&#xff1a;Docker和K8S安装版本匹配查看0.1&#xff1a;安装指定docker版本 **[1 — 7] ** [ 配置K8S主从集群前置准备操作 ]一&#xff1a;主节点操作 查看主机域名->编辑域名->域名配置二&#xff1a;安装自动填充&#xff0c;虚拟…

【炒股Zero To Hero】MACD金叉死叉到底是否有效,加上这个指标回报率增加197倍

移动平均收敛散度&#xff08;MACD - Moving Average Convergence Divergence&#xff09;是一种趋势跟踪动量指标&#xff0c;显示了证券价格的两个移动平均之间的关系。它用于识别趋势的方向和强度&#xff0c;属于技术分析中振荡器的一类。 MACD如何衡量股票及其趋势 有两…

基于“遥感+”蓝碳储量估算、红树林信息提取实践技术应用与科研论文写作

大气温室气体浓度不断增加&#xff0c;导致气候变暖加剧&#xff0c;随之会引发一系列气象、生态和环境灾害。如何降低温室气体浓度和应对气候变化已成为全球关注的焦点。海洋是地球上最大的“碳库”,“蓝碳”即海洋活动以及海洋生物&#xff08;特别是红树林、盐沼和海草&…