threejs顶点UV坐标、纹理贴图

news2025/6/2 8:45:21

1. 创建纹理贴图

通过纹理贴图加载器TextureLoader的load()方法加载一张图片可以返回一个纹理对象Texture,纹理对象Texture可以作为模型材质颜色贴图.map属性的值。

const geometry = new THREE.PlaneGeometry(200, 100); 
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./earth.jpg');
const material = new THREE.MeshLambertMaterial({
    // 设置纹理贴图:Texture对象作为材质map属性的属性值
    map: texture,//map表示材质的颜色贴图属性
});

颜色贴图属性.map

也可以通过颜色贴图属性.map直接设置纹理贴图,和材质的参数设置一样。

material.map = texture;

颜色贴图和color属性颜色值会混合

材质的颜色贴图属性.map设置后,模型会从纹理贴图上采集像素值,这时候一般来说不需要再设置材质颜色.color。.map贴图之所以称之为颜色贴图就是因为网格模型会获得颜色贴图的颜色值RGB。

颜色贴图map和color属性颜色值会混合。如果没有特殊需要,设置了颜色贴图.map,不用设置color的值,color默认白色0xffffff。

const material = new THREE.MeshLambertMaterial({
    // color: 0x00ffff,
    // 设置纹理贴图:Texture对象作为材质map属性的属性值
    map: texture,//map表示材质的颜色贴图属性
});

测试不同几何体添加纹理贴图的效果

你可以尝试把颜色纹理贴图映射到不同的几何体上查看渲染效果,至于为什么映射效果不同,其实和UV坐标相关,具体可以关注下节课关于UV坐标的讲解。

const geometry = new THREE.BoxGeometry(100, 100, 100); //长方体
const geometry = new THREE.SphereGeometry(60, 25, 25); //球体

注意!

注意最新版本,webgl渲染器默认编码方式已经改变,为了避免色差,纹理对象编码方式要修改为THREE.SRGBColorSpace

texture.colorSpace  = THREE.SRGBColorSpace;//设置为SRGB颜色空间

相关代码:

// 引入three.js
import * as THREE from "three";

// const geometry = new THREE.PlaneGeometry(200, 100); //矩形平面
// const geometry = new THREE.SphereGeometry(50); //矩形平面
const geometry = new THREE.BoxGeometry(100,100,100); //矩形平面
// 创建一个纹理加载器对象
const loadTex = new THREE.TextureLoader();
// 加载图片返回一个纹理对象Texture
const texture = loadTex.load("./earth.jpg");

const material = new THREE.MeshLambertMaterial({
  // color: 0x00ffff, //黄色线条
  map: texture, // 设置材质的颜色贴图:把图片作为mesh材质的贴图
});
// material.map = texture
const mesh = new THREE.Mesh(geometry, material);

export default mesh;

2. 自定义顶点UV坐标

学习自定义顶点UV坐标之前,首先保证你对BufferGeometry的顶点数据、纹理贴图都有一定的理解。

顶点UV坐标的作用

顶点UV坐标的作用是从纹理贴图上提取像素映射到网格模型Mesh的几何体表面上。

浏览器控制台查看threejs几何体默认的UV坐标数据。

const geometry = new THREE.PlaneGeometry(200, 100); //矩形平面
// const geometry = new THREE.BoxGeometry(100, 100, 100); //长方体
// const geometry = new THREE.SphereGeometry(100, 30, 30);//球体
console.log('uv',geometry.attributes.uv);

纹理贴图UV坐标范围

顶点UV坐标可以在0~1.0之间任意取值,纹理贴图左下角对应的UV坐标是(0,0),右上角对应的坐标(1,1)。

自定义顶点UVgeometry.attributes.uv

顶点UV坐标geometry.attributes.uv和顶点位置坐标geometry.attributes.position是一一对应的,

UV顶点坐标你可以根据需要在0~1之间任意设置,具体怎么设置,要看你想把图片的哪部分映射到Mesh的几何体表面上。

/**纹理坐标0~1之间随意定义*/
const uvs = new Float32Array([
    0, 0, //图片左下角
    1, 0, //图片右下角
    1, 1, //图片右上角
    0, 1, //图片左上角
]);
// 设置几何体attributes属性的位置normal属性
geometry.attributes.uv = new THREE.BufferAttribute(uvs, 2); //2个为一组,表示一个顶点的纹理坐标

获取纹理贴图四分之一

获取纹理贴图左下角四分之一部分的像素值

const uvs = new Float32Array([
    0, 0, 
    0.5, 0, 
    0.5, 0.5, 
    0, 0.5, 
]);

代码:

import * as THREE from 'three'
// 创建一个空的几何体顶对象
const geometry = new THREE.BufferGeometry()
// 添加顶点数据
// 类型化数组定义的一组顶点坐标数据
const vertices = new Float32Array([
  // 矩形平面的第一个三角形
  0, 0, 0, //顶点1坐标  0  索引
  160, 0, 0, //顶点2坐标  1
  160, 80, 0, //顶点3坐标  2
  0, 80, 0, //顶点6坐标  3
])

// BufferAttribute属性缓冲对象表示顶点数据
// 这个地方三个表示一个顶点坐标
const attribute = new THREE.BufferAttribute(vertices, 3)

// 设置几何体的顶点位置属性
geometry.attributes.position = attribute

const normals = new Float32Array([
  0, 0, 1, //顶点1法向量
  0, 0, 1, //顶点2法向量
  0, 0, 1, //顶点3法向量
  0, 0, 1, //顶点4法向量
])
// 定义了顶点法线数据或者说顶点法向量数据
geometry.attributes.normal = new THREE.BufferAttribute(normals, 3)

// 类型化数组创建顶点数据
const indexes = new Uint16Array([
  0,1,2,0,2,3
])

// 这个地方,一个索引表示一个顶点坐标
// 几何体顶点索引的定义
geometry.index = new THREE.BufferAttribute(indexes,1)

const uvs = new Float32Array([
  // 矩形平面的第一个三角形
  0, 0, //顶点1坐标  0  索引
  0.5, 0, //顶点2坐标  1
  0.5, 0.5, //顶点3坐标  2
  0, 0.5, //顶点6坐标  3
])
geometry.attributes.uv = new THREE.BufferAttribute(uvs, 2)

// 创建一个纹理加载器对象
const loadTex = new THREE.TextureLoader();
// 加载图片返回一个纹理对象Texture
const texture = loadTex.load("./earth.jpg");
// 用网格模型mesh渲染自定义的几何体BufferGeometry
// MeshBasicMaterial
const material = new THREE.MeshLambertMaterial({
  // color: 0x00ffff, //黄色线条
  // side: THREE.DoubleSide, //双面可见   BackSide 背面可见
  map: texture,
})

const mesh = new THREE.Mesh(geometry,material)
export default mesh

效果如下:扣出了这个地图的一部分

 

3. 圆形平面设置纹理贴图

你可以思考下,怎么实现矩形图片剪裁为圆形渲染。

其实很简单,可以通过圆形几何体CircleGeometry创建一个网格模型Mesh,把一张图片作为圆形Mesh材质的颜色贴图,这样就可以把一张方形图片剪裁渲染为圆形效果。

//CircleGeometry的顶点UV坐标是按照圆形采样纹理贴图
const geometry = new THREE.CircleGeometry(60, 100);
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
const texture = texLoader.load('./texture.jpg');
const material = new THREE.MeshBasicMaterial({
    map: texture,//map表示材质的颜色贴图属性
    side:THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geometry, material);

本质原理

CircleGeometry的UV坐标会对颜色纹理贴图.map进行提取,CircleGeometry的UV坐标默认提取的就是一个圆形轮廓。

 代码:

// 引入three.js
import * as THREE from "three";

// const geometry = new THREE.PlaneGeometry(100, 100); //矩形平面
// const geometry = new THREE.SphereGeometry(50); //矩形平面
// const geometry = new THREE.BoxGeometry(100,100,100); //矩形平面
// console.log('', geometry.attributes.uv);
const geometry = new THREE.CircleGeometry(50, 100);
// geometry.attributes.uv = 可以更改
// 创建一个纹理加载器对象
const texLoader = new THREE.TextureLoader();
// 加载图片返回一个纹理对象Texture
const texture = texLoader.load("./texture.jpg");

const material = new THREE.MeshLambertMaterial({
  // color: 0x00ffff, //黄色线条
  map: texture, // 设置材质的颜色贴图:把图片作为mesh材质的贴图
});
// material.map = texture
const mesh = new THREE.Mesh(geometry, material);

export default mesh;

 效果图:

4. 纹理对象Texture阵列

使用threejs纹理对象Texture的阵列功能+矩形平面几何体PlaneGeometry实现一个地面瓷砖效果。

矩形平面设置颜色贴图

const geometry = new THREE.PlaneGeometry(2000, 2000);
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./瓷砖.jpg');
const material = new THREE.MeshLambertMaterial({
    // 设置纹理贴图:Texture对象作为材质map属性的属性值
    map: texture,//map表示材质的颜色贴图属性
});
const mesh = new THREE.Mesh(geometry, material);

纹理对象Texture的阵列功能

// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./瓷砖.jpg');
// 设置阵列模式
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.set(12,12);//注意选择合适的阵列数量

旋转矩形平面

注意旋转方向影响矩形平面背面还是正面朝上,threejs默认渲染正面,不渲染背面。

// 旋转矩形平面
mesh.rotateX(-Math.PI/2);

 设置之前效果

代码:

// 引入three.js
import * as THREE from "three";

const geometry = new THREE.PlaneGeometry(2000, 2000); //矩形平面
// const geometry = new THREE.SphereGeometry(50); //矩形平面
// const geometry = new THREE.BoxGeometry(100,100,100); //矩形平面
// console.log('', geometry.attributes.uv);
// const geometry = new THREE.CircleGeometry(50, 100);
// 正好默认图片中间剪裁的,可以打印uv值,刚开始的8个uv值都是一样的
// geometry.attributes.uv = 可以更改
// 创建一个纹理加载器对象
const texLoader = new THREE.TextureLoader();
// .load 方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load("./瓷砖.jpg");
// 允许阵列模式
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(30, 30); //设置每个方向有多少个

const material = new THREE.MeshLambertMaterial({
  // color: 0x00ffff, //黄色线条
  map: texture, // 设置材质的颜色贴图:把图片作为mesh材质的贴图
});
// material.map = texture
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI/2)
export default mesh;

设置之后

5. 矩形Mesh+背景透明png贴图

three.js项目开发中,把一个背景透明的.png图像作为平面矩形网格模型Mesh的颜色贴图是一个非常有用的功能,通过这样一个功能,可以对three.js三维场景进行标注。

整体思路:创建一个矩形平面,设置颜色贴图.map,注意选择背景透明的.png图像作为颜色贴图,同时材质设置transparent: true,这样png图片背景完全透明的部分不显示。

// 矩形平面网格模型设置背景透明的png贴图
const geometry = new THREE.PlaneGeometry(60, 60); //默认在XOY平面上
const textureLoader = new THREE.TextureLoader();
const material = new THREE.MeshBasicMaterial({
    map: textureLoader.load('./指南针.png'),        
    transparent: true, //使用背景透明的png贴图,注意开启透明计算
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI / 2);

网格地面辅助观察GridHelper

// 添加一个辅助网格地面
const gridHelper = new THREE.GridHelper(300, 25, 0x004444, 0x004444);

矩形平面PlaneGeometry设置颜色贴图

const geometry = new THREE.PlaneGeometry(60, 60);
const textureLoader = new THREE.TextureLoader();
const material = new THREE.MeshBasicMaterial({
    map: textureLoader.load('./指南针.png'),
});
const mesh = new THREE.Mesh(geometry, material);

开启透明transparent: true

const material = new THREE.MeshBasicMaterial({
    map: textureLoader.load('./指南针.png'),   
    //transparent: true:使用背景透明的png贴图,注意允许透明   
    transparent: true, 
});

旋转平移矩形平面

PlaneGeometry矩形平面默认是在XOY平面上,如果你想平行于XOZ平面,就需要手动旋转。

mesh.rotateX(-Math.PI/2);//平行地面:矩形Mesh默认单面可见,注意旋转-Math.PI / 2

如果你不想矩形平面Mesh与地面网格线重合,可以通过位置属性.position偏移。

mesh.position.y = 1;//适当偏移,不与地面重合

 代码:

// 引入three.js
import * as THREE from "three";

const geometry = new THREE.PlaneGeometry(50, 50); //矩形平面
// const geometry = new THREE.SphereGeometry(50); //矩形平面
// const geometry = new THREE.BoxGeometry(100,100,100); //矩形平面
// console.log('', geometry.attributes.uv);
// const geometry = new THREE.CircleGeometry(50, 100);
// 正好默认图片中间剪裁的,可以打印uv值,刚开始的8个uv值都是一样的
// geometry.attributes.uv = 可以更改
// 创建一个纹理加载器对象
const textureLoader = new THREE.TextureLoader();
// .load 方法加载图像,返回一个纹理对象Texture
// const texture = texLoader.load("./瓷砖.jpg");
// // 允许阵列模式
// texture.wrapS = THREE.RepeatWrapping;
// texture.wrapT = THREE.RepeatWrapping;
// texture.repeat.set(30, 30); //设置每个方向有多少个

const material = new THREE.MeshLambertMaterial({
  color: 0x00ffff, //黄色线条
  map: textureLoader.load('./转弯.jpg'), // 设置材质的颜色贴图:把图片作为mesh材质的贴图
  transparent: true
});
// material.map = texture
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI/2)
mesh.rotateZ(Math.PI/2)
mesh.position.y = 1
export default mesh;

效果

 

6. UV动画

本节课通过纹理对象的偏移属性.offset给大家实现一个UV动画效果。

纹理对象.offset属性

纹理对象Texture的.offset的功能是偏移贴图在Mesh上位置,本质上相当于修改了UV顶点坐标。

texture.offset.x +=0.5;//纹理U方向偏移
texture.offset.y +=0.5;//纹理V方向偏移

纹理对象.wrapS或.wrapT与.offset组合使用

你可以对比,当你通过.offset设置了纹理映射偏移后,是否把.wrapS或.wrapT设置为重复映射模式THREE.RepeatWrapping,两种情况的渲染效果差异。

wrapS与x偏移量结合

texture.offset.x +=0.5;//纹理U方向偏移
// 设置.wrapS也就是U方向,纹理映射模式(包裹模式)
texture.wrapS = THREE.RepeatWrapping;//对应offste.x偏移

wrapT与y偏移量结合 

texture.offset.y +=0.5;//纹理V方向偏移
// 设置.wrapT也就是V方向,纹理映射模式
texture.wrapT = THREE.RepeatWrapping;//对应offste.y偏移

效果:

 

纹理UV动画

纹理对象Texture的.offset的功能是偏移贴图在Mesh上位置。

// 渲染循环
function render() {
    texture.offset.x +=0.001;//设置纹理动画:偏移量根据纹理和动画需要,设置合适的值
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();

纹理贴图阵列 + UV动画

通过阵列纹理贴图设置.map,这样的话贴图像素可以更小一些。

// 设置U方向阵列模式
texture.wrapS = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.x=50;//注意选择合适的阵列数量
// 渲染循环
function render() {
    texture.offset.x +=0.1;//设置纹理动画:偏移量根据纹理和动画需要,设置合适的值
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();

index.js,循环渲染

// 引入threejs
import * as THREE from "three";
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { mesh, texture } from "./model.js";

// 创建一个三维场景scene
const scene = new THREE.Scene();
scene.add(mesh);

// 创建一个三维坐标轴
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper); //将坐标轴对象添加到三维场景中

// 创建一个辅助网格地面的效果
// const girdHelper = new THREE.GridHelper(600, 50, 0x00ffff,0x004444);
// scene.add(girdHelper);

// 创建一个光源对象  点光源
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.decay = 0.0; //不随着距离的改变而衰减
pointLight.position.set(400, 200, 300); //偏移光源位置,观察渲染效果变化
// scene.add(pointLight); //点光源添加到场景中

//可视化点光源
// const pointLightHelper = new THREE.PointLightHelper(pointLight, 10);
// scene.add(pointLightHelper);
// 添加一个环境光
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient); //没有方向,也就没有立体的

// 删除
// scene.remove(ambient, model);
// scene.remove(ambient)
// scene.remove(model)

// 添加一个平行光
const directionalLight = new THREE.DirectionalLight(0xfffff, 0.8);
directionalLight.position.set(100, 100, 100); //棱角很弱,跟每个面的夹角都一样
directionalLight.position.set(100, 60, 50); //可以看出每个面的棱角不一样
// directionalLight.target = mesh; //默认坐标原点
scene.add(directionalLight);

// 定义相机输出画布的尺寸(单位:像素px)
const width = window.innerWidth;
const height = window.innerHeight;
// 设置相机的四个参数

// 创建一个透视投影相机对象
const camera = new THREE.PerspectiveCamera(30, width / height, 0.1, 8000);
// 设置相机的位置
camera.position.set(200, 200, 200); //相机在Three.js三维坐标系中的位置
// 相机的视线,观察目标点的坐标
camera.lookAt(0, 0, 0); //坐标原点

// 创建一个WebGL渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true, //启用抗锯齿,线条更加流畅,减少锯齿状
});
renderer.setSize(width, height); //canvas画布的宽高度
renderer.render(scene, camera); //执行一个渲染操作,类比相机的拍照动作 咔
//把渲染结果canvas画布,也就是所谓的“照片”,添加到网页的页面上
document.body.appendChild(renderer.domElement);
// 插入到任意的html元素中
// document.getElementById("webgl").appendChild(renderer.domElement)

console.log("查看当前屏幕设备像素比", window.devicePixelRatio); //查看当前屏幕设备像素比 2
// 告诉threejs你的屏幕的设备像素比window.devicePixelRatio,针对与像素接近于1的设置下面的语句可能不是很明显,对于屏幕比例是2的,高清屏这种,设置的效果会很明显,减少模糊
renderer.setPixelRatio(window.devicePixelRatio); //会很清晰,遇到模糊了不要忘记设置这个
// renderer.setClearColor(0x444444);

// 渲染循环
function render() {
  // 可以与wrapS结合一起思考,拼接的作用效果,会让第一张图片拼接完了之后,剩余的部分依然存在图片
  // 每次累加
  texture.offset.x += 0.1;
  // model.rotateY(0.01); //周期性旋转,每次旋转0.01弧度
  renderer.render(scene, camera); //周期性执行相机渲染功能,更新canvas画布上的内容
  requestAnimationFrame(render);
}
render();

// 创建一个相机控件对象
const controls = new OrbitControls(camera, renderer.domElement);
// controls.target.set(1000, 0, 1000); //默认为0,0,0
controls.update();
// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
controls.addEventListener("change", function () {
  // console.log(camera.position);
  // 每当发生改变的时候就重新渲染
  renderer.render(scene, camera); //执行渲染操作
});

window.onresize = function () {
  // 更新canvas画布的尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 相机的视椎体宽高比一定和画布保持一致,否则物体就会扭曲
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
};

 model.js

// 引入three.js
import * as THREE from "three";

const geometry = new THREE.PlaneGeometry(200, 20); //矩形平面
// const geometry = new THREE.SphereGeometry(50); //矩形平面
// const geometry = new THREE.BoxGeometry(100,100,100); //矩形平面

// 创建一个纹理加载器对象
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("./纹理3.jpg");
const material = new THREE.MeshLambertMaterial({
  // color: 0x00ffff, //黄色线条
  map: texture,
});

const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI / 2);
// 纹理对象的偏移属性
// texture.offset.x = 0.5; //UV坐标的 u方向偏移 其余部分会被砍掉
// texture.offset.y = -0.5; //UV坐标的 v方向偏移
// 映射之后,会将多余的挪动到后面并拼接起来
texture.wrapS = THREE.RepeatWrapping; //改变包裹,或者说映射方式
// 不阵列的话,那么一整个图片就会缩放在这个地方
texture.repeat.x = 50; //
export { mesh, texture };

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- <div id="webgl" style="margin-top: 100px;margin-left: 200px;"></div> -->
    <script type="importmap">
      {
        "imports": {
          "three": "../../three.js-r148/build/three.module.js",
          "three/addons/": "../../three.js-r148/examples/jsm/"
        }
      }
    </script>
    <script type="module" src="./index.js"></script>
  </body>
</html>

模拟传送带的效果,动图,滚动的效果

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

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

相关文章

STM32 RTC实时时钟\BKP备份寄存器\时间戳

一、Unix时间戳 想要计算当地北京时间&#xff0c;需要根据经度和闰年之类的运算得到(c语言里面可以调用time.h的函数) 二、UTC/GMT&#xff08;科普&#xff09; 三、时间戳转化 C语言的time.h模块提供了时间获取和时间戳转换的相关函数&#xff0c;可以方便的进行秒计数器、…

Axure设计案例——科技感立体柱状图

想让你的数据展示告别平淡无奇&#xff0c;成为吸引全场目光的焦点吗&#xff1f;快来瞧瞧这个Axure设计的科技感立体柱状图案例&#xff01;科技感设计风格借助逼真的立体效果打破传统柱状图的平面感&#xff0c;营造出一种令人眼前一亮的视觉震撼。每一个柱状体都仿佛是真实存…

app获取相册权限是否意味着所有相片都可随时读取?

针对安卓手机相册的隐私安全问题&#xff0c;我也比较好奇&#xff0c;App授予了相册权限&#xff0c;真的能自动读取用户的照片吗&#xff1f;最近做了一个小实验&#xff0c;我开发了2个小App&#xff0c;这2个App安装的时候只授予了相册权限&#xff0c;没有授予其他任何权限…

2025年05月29日Github流行趋势

项目名称&#xff1a;agenticSeek 项目地址url&#xff1a;https://github.com/Fosowl/agenticSeek项目语言&#xff1a;Python历史star数&#xff1a;11898今日star数&#xff1a;2379项目维护者&#xff1a;Fosowl, steveh8758, klimentij, ganeshnikhil, apps/copilot-pull-…

第十一节:第一部分:正则表达式:应用案例、爬取信息、搜索替换

正则表达式介绍 String提供的正则表达式的方法的书写规则 正则表达式总结 正则表达式作用&#xff1a; 作用三&#xff1a;搜索替换 案例分析及代码&#xff08;图片解析&#xff09; 代码&#xff1a; 代码一&#xff1a;校验手机号和邮箱格式是否正确 package com.itheima.…

新能源集群划分+电压调节!基于分布式能源集群划分的电压调节策略!

适用平台&#xff1a;MatlabYalmip Cplex (具体操作已在程序文件中说明) 参考文献&#xff1a;基于分布式能源集群化分的电压调节策略[D]. 一、文献解读 1. 主要内容/创新点 提出了一种基于分布式能源集群化的电压调节策略&#xff0c;计及分布式能源的有功、无功调节能力&a…

端午安康 | 以匠心,致长远

端午节快乐 值此端午佳节&#xff0c;数图衷心感谢每一位合作伙伴与客户的信任相伴。 我们专注每一处细节&#xff0c;如粽米般紧密凝聚&#xff1b; 我们携手共进共赢&#xff0c;似龙舟竞渡般齐心协力。 未来&#xff0c;我们愿继续以创新为桨&#xff0c;与您共划时代新篇…

漫画Android:事件分发的过程是怎样的?

当用户触摸屏幕时&#xff0c;硬件层会捕获触摸信号&#xff0c;并将其转化为内核事件。 Android系统会通过InputManagerService和WindowManagerService等服务将这些事件包装成MotionEvent对象&#xff0c;并将其传递给Activity的dispatchTouchEvent()方法中&#xff0c;Activi…

2022 RoboCom 世界机器人开发者大赛-本科组(省赛)解题报告 | 珂学家

前言 题解 2022 RoboCom 世界机器人开发者大赛-本科组&#xff08;省赛&#xff09;。 感觉T5是最简单的&#xff0c;其他都不好做。 RC-u5 树与二分图 分值: 30分 思路: 容斥原理 树天然就是二分图&#xff0c;按深度d归类(偶数深度为S1&#xff0c;奇数深度为S2)&#x…

如何用ChatGPT提升学术长文质量

目录 一、关于让人工智能充当评审专家 二、关于分批次输入论文内容 三、来看看提示词 大家好这里是学术Anan&#xff0c;官网&#x1f449;AIWritePaper~ 论文完成初稿之后&#xff0c;一般情况下&#xff0c;宝子们还需要找专家给我们提出评审意见。找专家评审其实并不容易…

BKP(备份寄存器)和 RTC(实时时钟)

什么是BKP&#xff1f; 备份寄存器&#xff08;BackupRegister&#xff09;是42个16位的寄存器&#xff08;不同设备存在差异&#xff1a;20字节&#xff08;中容量和小容量&#xff09;/84字节&#xff08;大容量和互联型&#xff09;&#xff09;&#xff0c;可用来存储 最多…

【EdgeYOLO】《EdgeYOLO: An Edge-Real-Time Object Detector》

Liu S, Zha J, Sun J, et al. EdgeYOLO: An edge-real-time object detector[C]//2023 42nd Chinese Control Conference (CCC). IEEE, 2023: 7507-7512. CCC-2023 源码&#xff1a;https://github.com/LSH9832/edgeyolo 论文&#xff1a;https://arxiv.org/pdf/2302.07483 …

调试技巧总结

目录 一.调试1.什么是调试2.调试语义的分类2.1 静态语义2.2 动态语义 二.实用的调试技巧1.屏蔽代码2.借助打印3.查看汇编代码4.调试技巧总结 一.调试 1.什么是调试 调试&#xff0c;通俗易懂地说就是不断排查代码的错误&#xff0c;进行修正的过程&#xff0c;在写代码的时候…

ubuntu安装blender并配置应用程序图标

ubuntu安装blender并配置应用程序图标 下载blender安装包解压缩并安装启动blender添加应用程序启动图标 下载blender安装包 blender中文服务站的下载网址 这里选择Linux 64位的Blender 4.2.4 LTS。下载速度很快。下载得到 解压缩并安装 将下载的压缩包放在/opt目录下&#…

基于LBS的上门代厨APP开发全流程解析

上门做饭将会取代外卖行业成为新一轮的创业风口吗&#xff1f;杭州一位女士的3菜一汤88元套餐引爆社交网络&#xff0c;这个包含做饭、洗碗、收拾厨房的全套服务&#xff0c;正在重新定义"到家经济"的边界。当25岁的研究生系着围裙出现在客户厨房&#xff0c;当年轻姑…

Redisson学习专栏(三):高级特性与实战(Spring/Spring Boot 集成,响应式编程,分布式服务,性能优化)

文章目录 前言一、Spring Boot深度整合实战1.1 分布式缓存管理1.2 声明式缓存1.3 响应式编程 二、分布式服务治理2.1 服务端实现2.2 客户端调用2.3 高级特性2.4 服务治理功能 三、分布式任务调度引擎四、连接池配置与网络参数调优4.1 连接池配置4.2 网络参数调优4.3 集群模式特…

华为欧拉系统中部署FTP服务与Filestash应用:实现高效文件管理和共享

华为欧拉系统中部署FTP服务与Filestash应用:实现高效文件管理和共享 前言一、相关服务介绍1.1 Huawei Cloud EulerOS介绍1.2 Filestash介绍1.3 华为云Flexus应用服务器L实例介绍二、本次实践介绍2.1 本次实践介绍2.2 本次环境规划三、检查云服务器环境3.1 登录华为云3.2 SSH远…

基于Docker和YARN的大数据环境部署实践最新版

基于Docker和YARN的大数据环境部署实践 目的 本操作手册旨在指导用户通过Docker容器技术&#xff0c;快速搭建一个完整的大数据环境。该环境包含以下核心组件&#xff1a; Hadoop HDFS/YARN&#xff08;分布式存储与资源调度&#xff09;Spark on YARN&#xff08;分布式计算…

【大模型】Bert

一、背景与起源 上下文建模的局限&#xff1a;在 BERT 之前&#xff0c;诸如 Word2Vec、GloVe 等词向量方法只能给出静态的词表示&#xff1b;而基于单向或浅层双向 LSTM/Transformer 的语言模型&#xff08;如 OpenAI GPT&#xff09;只能捕捉文本从左到右&#xff08;或右到…

3 分钟学会使用 Puppeteer 将 HTML 转 PDF

需求背景 1、网页存档与文档管理 需要将网页内容长期保存或归档为PDF,确保内容不被篡改或丢失,适用于法律文档、合同、技术文档等场景。PDF格式便于存储和检索。 2、电子报告生成 动态生成的HTML内容(如数据分析报告、仪表盘)需导出为PDF供下载或打印。PDF保留排版和样…