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

Three.js相机Camera控件知识梳理

原文:https://juejin.cn/post/7231089453695238204?searchId=20241217193043D32C9115C2057FE3AD64

1. 相机类型

Three.js 主要提供了两种类型的相机:正交相机(OrthographicCamera)和透视相机(PerspectiveCamera)。

1.1 正交相机

正交相机(OrthographicCamera)使用正交投影进行渲染。在正交投影中,物体的大小不会随着距离的增加而减小,这意味着所有物体在渲染时保持相同的尺寸,不受距离的影响。这种相机在制作 2D 游戏和 CAD 工具等应用中非常有用。

创建正交相机的代码如下:

1

2

3

4

5

6

7

const camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);

// 正投影相机案例

const width = window.innerWidth; //canvas画布宽度

const height = window.innerHeight; //canvas画布高度

const k = width / height; //canvas画布宽高比

const s = 600;//控制left, right, top, bottom范围大小

const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);

参数(属性)含义
left渲染空间的左边界
right渲染空间的右边界
top渲染空间的上边界
bottom渲染空间的下边界
nearnear属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 默认值0.1
farfar属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到。 默认值2000

1.2 透视相机

透视相机(PerspectiveCamera)使用透视投影进行渲染。在透视投影中,物体的大小会随着距离的增加而减小,这使得远离相机的物体看起来更小,符合现实世界中的透视效果。这种相机在制作 3D 游戏和仿真应用中非常常见。

创建透视相机的代码如下:

1

2

3

4

5

6

7

const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

//透视相机案例

// width和height用来设置Three.js输出的Canvas画布尺寸(像素px)

const width = 800; //宽度

const height = 500; //高度

// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000:远裁截面

const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);

参数含义
fov相机视锥体竖直方向视野角度
aspect相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height
near相机视锥体近裁截面相对相机距离
far相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向

2. 相机属性

Three.js 中的相机具有一些基本属性,这些属性决定了相机的视角和视野。

2.1 视角(FOV)

仅透视相机具有视角属性(FOV)。视角表示相机的垂直视野范围,单位为度。较大的视角值会导致更大的视野,但可能会产生畸变。较小的视角值则会产生更窄的视野和更低的畸变。

2.2 宽高比(Aspect)

仅透视相机具有宽高比属性。宽高比表示相机水平视野范围与垂直视野范围的比值。通常,宽高比应该与渲染目标(如 Canvas 或 WebGLRenderTarget)的宽高比相同,以避免图像被拉伸或压缩。

2.3 近裁剪面(Near)和远裁剪面(Far)

近裁剪面和远裁剪面定义了相机的渲染范围。位于近裁剪面之前的物体和位于远裁剪面之后的物体都不会被渲染。为了提高渲染性能,通常应该尽量将近裁剪面和远裁剪面之间的距离设置得较小。

3. 不同方向的投影视图

3.1 x轴方向观察

1

2

3

4

5

// 通过UI按钮改变相机观察角度

document.getElementById('x').addEventListener('click', function () {

    camera.position.set(500, 0, 0); //x轴方向观察

    camera.lookAt(0, 0, 0); //重新计算相机视线方向

})

3.2 y轴方向观察

1

2

3

4

5

// 通过UI按钮改变相机观察角度

document.getElementById('y').addEventListener('click', function () {

    camera.position.set(0, 500, 0); //y轴方向观察

    camera.lookAt(0, 0, 0); //重新计算相机视线方向

})

3.3 z轴方向观察z轴方向观察

1

2

3

4

5

// 通过UI按钮改变相机观察角度

document.getElementById('z').addEventListener('click', function () {

    camera.position.set(0, 0, 500); //z轴方向观察

    camera.lookAt(0, 0, 0); //重新计算相机视线方向

})

4. 相机动画(.position和.lookAt())

通过相机对象Camera.position属性和.lookAt()方法,可实现一段相机动画。

4.1 相机运动动画

改变相机的位置.position,三维场景在canvas画布上呈现不同的效果,如果连续改变相机的位置.position,就可以获得一个动画效果。

课件案例源码是一个工厂模型,相机在空中俯视工厂,如果在渲染循环中不停地改变相机位置,这时候产生的视觉效果,就好比你在天上运动,看地面的效果。

1

2

3

4

5

6

7

// 渲染循环

function render() {

    camera.position.z -= 0.3;//相机直线运动动画

    renderer.render(scene, camera);

    requestAnimationFrame(render);

}

render();

4.2 相机圆周运动相机圆周运动

在渲染循环中,改变相机位置,在XOZ平面上绕着y轴圆周运动。

1

2

3

4

5

6

7

8

9

10

11

12

// 渲染循环

let angle = 0; //用于圆周运动计算的角度值

const R = 100; //相机圆周运动的半径

function render() {

    angle += 0.01;

    // 相机y坐标不变,在XOZ平面上做圆周运动

    camera.position.x = R * Math.cos(angle);

    camera.position.z = R * Math.sin(angle);

    renderer.render(scene, camera);

    requestAnimationFrame(render);

}

render();

4.3 执行lookAt()计算相机视线方向

改变.position属性后,如果不执行.lookAt()方法,相机的观察方向默认不变。

如果你希望相机圆周运动的同时,改变相机视线方向,保持相机镜头始终指向坐标原点或其它位置,需要每次改变.position属性后,重新执行一遍.lookAt()方法

1

2

3

4

5

6

7

8

9

function render() {

    angle += 0.01;

    camera.position.x = R * Math.cos(angle);

    camera.position.z = R * Math.sin(angle);

    // .position改变,重新执行lookAt(0,0,0)计算相机视线方向

    camera.lookAt(0,0,0);

    requestAnimationFrame(render);

}

render();

5. 相机控件OrbitControls

通常需要为用户提供一种直观的方式来浏览和操作场景。OrbitControls 是 Three.js 提供的一种常用的相机控制器,允许用户通过鼠标或触摸屏操作来旋转、平移和缩放场景。

5.1 OrbitControls使用

  • 旋转:拖动鼠标左键
  • 缩放:滚动鼠标中键
  • 平移:拖动鼠标右键

OrbitControls本质上就是改变相机的参数,比如相机的位置属性,改变相机位置也可以改变相机拍照场景中模型的角度,实现模型的360度旋转预览效果,改变透视投影相机距离模型的距离,就可以改变相机能看到的视野范围。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

// 引入轨道控制器扩展库OrbitControls.js

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

// 设置相机控件轨道控制器OrbitControls

const controls = new OrbitControls(camera, renderer.domElement);

// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景

controls.addEventListener('change', function () {

    renderer.render(scene, camera); //执行渲染操作

    console.log('camera.position',camera.position);

});//监听鼠标、键盘事件

//相关限制方法:

controls.enablePan = false; //禁止平移

controls.enableZoom = false;//禁止缩放

controls.enableRotate = false; //禁止旋转

// 缩放范围

controls.minZoom = 0.5;

controls.maxZoom = 2;

// 上下旋转范围

controls.minPolarAngle = 0;

controls.maxPolarAngle = Math.PI/2;

// 左右旋转范围

controls.minAzimuthAngle = -Math.PI/2;

controls.maxAzimuthAngle = Math.PI/2;

//更新方法

function animate() {

  requestAnimationFrame(animate);

  // 更新控制器

  controls.update();

  // 渲染场景

  renderer.render(scene, camera);

}

6. 相机控件MapControls

在某些 Three.js 应用中,例如地图、地形或者 GIS 类型的项目,需要为用户提供一种直观且符合习惯的方式来浏览和操作场景。MapControls 是一个类似于 Google Maps 风格的相机控制器,允许用户通过鼠标和触摸屏操作来平移、缩放和旋转场景。

6.1 MapControls使用

  • 平移:鼠标左键拖动
  • 旋转:鼠标右键拖动
  • 缩放:鼠标中键滚动

MapControls本质上就是改变相机的参数,比如相机的位置属性、相机目标观察点。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

// 引入相机控件`MapControls`

import { MapControls } from 'three/addons/controls/OrbitControls.js';

const controls = new MapControls(camera, renderer.domElement);

controls.addEventListener('change', function () {

    // 鼠标右键旋转时候,查看.position变化

    // 鼠标左键拖动的时候,查看.position、.target的位置会变化

    console.log('camera.position',camera.position);

    console.log('controls.target',controls.target);

});

//相关限制方法:

controls.enablePan = false; //禁止平移

controls.enableZoom = false;//禁止缩放

controls.enableRotate = false; //禁止旋转

//相机位置与观察目标点最小值

controls.minDistance = 200;

//相机位置与观察目标点最大值

controls.maxDistance = 500;

// 上下旋转范围

controls.minPolarAngle = 0;

controls.maxPolarAngle = Math.PI/2;

// 左右旋转范围

controls.minAzimuthAngle = -Math.PI/2;

controls.maxAzimuthAngle = Math.PI/2;

//更新方法

function animate() {

  requestAnimationFrame(animate);

  // 更新控制器

  controls.update();

  // 渲染场景

  renderer.render(scene, camera);

}

7. 窗口变化的自适应渲染

在开发 Three.js 项目时,我们需要考虑到不同的设备和屏幕尺寸。当用户调整浏览器窗口大小时,我们希望场景能够自适应地进行调整,以保持正确的比例和尺寸。

要实现自适应渲染,我们需要在浏览器窗口大小发生变化时更新相机和渲染器的设置。首先,我们需要为 window 对象添加一个 resize 事件监听器:

1

window.addEventListener('resize', onWindowResize);

接下来,我们定义 onWindowResize 函数。在这个函数中,我们需要完成以下任务:

  • 更新相机的宽高比(aspect)。
  • 更新相机的投影矩阵。
  • 更新渲染器的大小。

7.1 正投影相机OrthographicCamera自适应渲染

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// onresize 事件会在窗口被调整大小时发生

function onWindowResize(){

  // 重置渲染器输出画布canvas尺寸

  renderer.setSize(window.innerWidth,window.innerHeight);

  // 重置相机投影的相关参数

  k = window.innerWidth/window.innerHeight;//窗口宽高比

  camera.left = -s*k;

  camera.right = s*k;

  camera.top = s;

  camera.bottom = -s;

  // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix

  // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)

  // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵

  camera.updateProjectionMatrix ();

};

7.2 透视投影相机PerspectiveCamera自适应渲染

1

2

3

4

5

6

7

8

9

10

11

// onresize 事件会在窗口被调整大小时发生

function onWindowResize(){

  // 重置渲染器输出画布canvas尺寸

  renderer.setSize(window.innerWidth,window.innerHeight);

  // 全屏情况下:设置观察范围长宽比aspect为窗口宽高比

  camera.aspect = window.innerWidth/window.innerHeight;

  // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix

  // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)

  // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵

  camera.updateProjectionMatrix ();

};

以上就是Three.js相机Camera的详细内容,更多关于Three.js相机Camera的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:

  • Three.js引用和环境搭建过程详解
  • Three.js概述和基础知识学习
  • Three.js材质Material类型示例详解
  • Three.js PBR物理渲染属性及使用介绍
  • Three.js 中的屏幕空间环境光遮蔽SSAO
  • Three.js物理引擎Cannon.js创建简单应用程序
  • Three.js中实现Bloom效果及完整示例
  • THREE.js添加多个castShadow光源报错解决及原因分析

相关文章:

Three.js相机Camera控件知识梳理

原文:https://juejin.cn/post/7231089453695238204?searchId20241217193043D32C9115C2057FE3AD64 1. 相机类型 Three.js 主要提供了两种类型的相机:正交相机(OrthographicCamera)和透视相机(PerspectiveCamera&…...

Unity 开发Apple Vision Pro空间锚点应用Spatial Anchor

空间锚点具有多方面的作用 虚拟物体定位与固定: 位置保持:可以把虚拟物体固定在现实世界中的特定区域或位置。即使使用者退出程序后再次打开,之前锚定过的虚拟物体仍然能够出现在之前所锚定的位置,为用户提供连贯的体验。比如在一…...

BGP的六种状态分别是什么?

此文章主要简单介绍下BGP的六种状态 1.Idle BGP会话的初始状态,路由器在此状态下不与任何BGP邻居通信,通常标识会话还没有开始或由于错误而未能启动,一般来说,缺乏去往BGP对等体的路由是导致BGP路由器其状态一直处于idle状态的常…...

IDEA搭建SpringBoot,MyBatis,Mysql工程项目

目录 一、前言 二、项目结构 三、初始化项目 四、SpringBoot项目集成Mybatis编写接口 五、代码仓库 一、前言 构建一个基于Spring Boot框架的现代化Web应用程序,以满足[公司/组织名称]对于[业务需求描述]的需求。通过利用Spring Boot简化企业级应用开发的优势&…...

Reactor

文章目录 正确的理解发送double free问题 1.把我们的reactor进行拆分2.链接管理3.Reactor的理论 listensock只需要设置_recv_cb,而其他sock,读,写,异常 所以今天写nullptr其实就不太对,添加为空就没办法去响应事件 获…...

在ESP32使用AT指令集与服务器进行TCP/IP通信时,<link ID> 解释

在ESP32使用AT指令集与服务器进行TCP/IP通信时&#xff0c;<link ID> 是一个非常重要的参数。它用于标识不同的连接实例&#xff0c;特别是在多连接场景下&#xff08;如同时建立多个TCP或UDP连接&#xff09;。每个连接都有唯一的<link ID>&#xff0c;通过这个ID…...

[SZ901] JTAG合并功能(类似FPGA菊花链)

SZ901 JTAG支持将JTAG端口组合&#xff0c;最多将四个JTAG变成一个 设置如下 Vivado 识别结果如下 两块板子&#xff0c;变成一组&#xff0c;&#xff0c;可以同时抓取信号&#xff0c;调试&#xff01; SZ901 已上架淘宝&#xff0c;搜素“SZ901”哦...

paimon中的Tag

TAG 在传统数仓场景中&#xff0c;从传统数据库中导入的事实表数据一般是全量导入&#xff0c;按天分区每天都存储一份全量数据&#xff0c;paimon对此提供了Tag机制&#xff0c;创建TAG时&#xff0c;会对当前数据做一份全量快照&#xff0c;在之后对表的数据进行更新也不会影…...

3分钟读懂数据分析的流程是什么

数据分析是基于商业目的&#xff0c;有目的地进行收集、整理、加工和分析数据&#xff0c;提炼出有价值的 信息的一个过程。整个过程大致可分为五个阶段&#xff0c;具体如下图所示。 1.明确目的和思路 在开展数据分析之前&#xff0c;我们必须要搞清楚几个问题&#xff0c;比…...

uniapp入门 01创建项目模版

0安装 hbuilder x 标准版 1.创建模版工程 2.创建官方 案例工程 index.uvuewen 文件解析 <!-- 模版 标签 --> <template><view></view></template><!-- 脚本 --> <script>export default {data() {return {}},onLoad() {},methods:…...

React 19新特性探索:提升性能与开发者体验

React作为最受欢迎的JavaScript库之一&#xff0c;不断推出新版本以应对日益复杂的应用需求。React 19作为最新的版本&#xff0c;引入了一系列令人兴奋的新特性和改进&#xff0c;旨在进一步提升应用的性能、开发效率和用户体验。 本文将深入探讨React 19的新特性&#xff0c;…...

Hive是什么,Hive介绍

官方网站&#xff1a;Apache Hive Hive是一个基于Hadoop的数据仓库工具&#xff0c;主要用于处理和查询存储在HDSF上的大规模数据‌。Hive通过将结构化的数据文件映射为数据库表&#xff0c;并提供类SQL的查询功能&#xff0c;使得用户可以使用SQL语句来执行复杂的​MapReduce任…...

[LeetCode-Python版] 定长滑动窗口1(1456 / 643 / 1343 / 2090 / 2379)

思路 把问题拆解成三步&#xff1a;入-更新-出。 入&#xff1a;下标为 i 的元素进入窗口&#xff0c;更新相关统计量。如果 i<k−1 则重复第一步。更新&#xff1a;更新答案。一般是更新最大值/最小值。出&#xff1a;下标为 i−(k-1) 的元素离开窗口&#xff0c;更新相关…...

imx6ull qt多页面控制系统(正点原子imx系列驱动开发)

开题答辩完了也考完了四六级&#xff0c;赶紧来更新一下一个月前留下的坑吧 QAQ首先&#xff0c;因为毕业设计需要用到这些知识所以就从网络上找了一个智能车机系统&#xff0c;借鉴了一下大佬的项目思路&#xff0c;缝缝补补一个月终于完成了这一内容。 在这里先感谢从两位大佬…...

OCR:文字识别

使用场景: 远程身份认证 自动识别录入用户身份/企业资质信息&#xff0c;应用于金融、政务、保险、电商、直播等场景&#xff0c;对用户、商家、主播进行实名身份认证&#xff0c;有效降低用户输入成本&#xff0c;控制业务风险 文档电子化 识别提取各类办公文档、合同文件、企…...

SQL Server通过存储过程实现自定义邮件格式并定时发送

在 SQL Server 中,可以通过存储过程实现自定义邮件格式并定时发送。这通常涉及以下几个步骤: 1. 配置 Database Mail:首先需要配置 SQL Server 的 Database Mail 功能。 2. 创建存储过程:编写存储过程来生成自定义邮件格式并发送邮件。 3. 设置 SQL Server 代理作…...

【进阶编程】MVC和MVVM实现前后端分离的实现

在 WPF 开发中&#xff0c;通常使用 MVVM&#xff08;Model-View-ViewModel&#xff09;架构来分离视图和业务逻辑&#xff0c;但在某些情况下&#xff0c;你可能希望将 MVC&#xff08;Model-View-Controller&#xff09;模式与 MVVM 结合使用。这种结合有时是为了兼顾不同的架…...

HT81297 18W内置升压单声道D类音频功放

1、特征 扩频技术 输出功率 18W(VBAT3.7V, RL4Ω, THDN10%, fN 1kHz) 16W(VBAT3.7V,RL-4Ω,THDN1%,fN1kHz) 8W(VBAT3.3V,RL-8Ω,THDN1%, fN1kHz) VBAr供电范围:3.0V至12V 高效H类升压功能 -自适应功放功率的升压轨&#xff0c;延长电池播放时间 (HT81297A) -可调节最大限流值&…...

linux ipmitool配置机器的BMC(服务器管理后台)

前置&#xff1a;mgnt口和网卡1连接入内网&#xff0c;并分配静态ip 1. 安装 ipmitool Debian/Ubuntu: sudo apt-get update sudo apt-get install ipmitool CentOS/RHEL: sudo yum install ipmitool2. 配置 BMC 的 IP 地址 #打印当前ipmi 地址配置信息。 ipmitool lan p…...

【项目实战】location.href 实现文件下载

应用场景 最近在项目中看到一种新的文件下载方式,原理是将[后台地址接口地址请求参数]拼接成一个url,直接将下载任务丢给浏览器去执行.但是在需要校验token的项目中,需要后台单独给这个接口放开token校验 location.href 相关内容 window.location.protocol: 返回当前 URL 的…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

免费批量Markdown转Word工具

免费批量Markdown转Word工具 一款简单易用的批量Markdown文档转换工具&#xff0c;支持将多个Markdown文件一键转换为Word文档。完全免费&#xff0c;无需安装&#xff0c;解压即用&#xff01; 官方网站 访问官方展示页面了解更多信息&#xff1a;http://mutou888.com/pro…...

React、Git、计网、发展趋势等内容——前端面试宝典(字节、小红书和美团)

React React Hook实现架构、.Hook不能在循环嵌套语句中使用 , 为什么&#xff0c;Fiber架构&#xff0c;面试向面试官介绍&#xff0c;详细解释 用户: React Hook实现架构、.Hook不能在循环嵌套语句中使用 , 为什么&#xff0c;Fiber架构&#xff0c;面试向面试官介绍&#x…...