一、模型对象旋转平移缩放变换
点模型
Points
、线模型Line
、网格网格模型Mesh
等模型对象的基类都是Object3D
, 如果想对这些模型进行旋转、缩放、平移等操作,如何实现, 可以查询three.ts
文档Object3D
对相关属性和方法的介绍。
1. 缩放
- 网格模型
Mesh
的属性.scale
表示模型对象的缩放比例,默认值是THREE.Vector3(1.0,1.0,1.0)
,.scale
的属性值是一个三维向量对象Vector3
,查看three.ts
文档可以知道Vector3
对象具有属性.x、.y、.z
,Vector3
对象还具有方法.set()
,.set
方法有三个表示xyz
方向缩放比例的参数。 - 网格模型xyz方向分别缩放
0.5,1.5,2
倍javascriptmesh.scale.set(0.5, 1.5, 2)
- x轴方向放大2倍javascript
mesh.scale.x = 2.0;
2. 位置属性.position
- 模型位置
.position
属性和.scale
属性的属性值一样也是三维向量对象Vector3
, 通过模型位置属性.position
可以设置模型在场景Scene
中的位置。 模型位置.position
的默认值是THREE.Vector3(0.0,0.0,0.0)
。 - 设置网格模型y坐标javascript
mesh.position.y = 80;
- 设置模型xyz坐标javascript
mesh.position.set(80, 2, 10);
3. 平移
- 网格模型沿着
x
轴正方向平移100
,可以多次执行该语句,每次执行都是相对上一次的位置进行平移变换。javascript// 等价于mesh.position = mesh.position + 100; mesh.translateX(100); // 沿着x轴正方向平移距离100
- 沿着Z轴负方向平移距离50。javascript
mesh.translateZ(-50);
- 沿着自定义的方向移动。javascript执行
// 向量Vector3对象表示方向 const axis = new THREE.Vector3(1, 1, 1); axis.normalize(); //向量归一化 //沿着axis轴表示方向平移100 mesh.translateOnAxis(axis, 100);
.translateX()
、.translateY()
、.translateOnAxis()
等方法本质上改变的都是模型的位置属性.position
。
4. 旋转
- 立方体网格模型绕立方体的
x
轴旋转π/4
,可以多次执行该语句,每次执行都是相对上一次的角度进行旋转变化。javascriptmesh.rotateX(Math.PI / 4); // 绕x轴旋转π/4
- 网格模型绕(0,1,0)向量表示的轴旋转
π/8
javascriptconst axis = new THREE.Vector3(0, 1, 0);//向量axis mesh.rotateOnAxis(axis,Math.PI / 8);//绕axis轴旋转π/8
- 执行旋转
.rotateX()
等方法和执行平移.translateY()
等方法一样都是对模型状态属性的改变, 区别在于执行平移方法改变的是模型的位置属性.position
,执行模型的旋转方法改变的是表示模型角度状态的角度属性.rotation
或者四元数属性.quaternion
。 - 模型的角度属性
.rotation
和四元数属性.quaternion
都是表示模型的角度状态,只是表示方法不同,.rotation
属性值是欧拉对象Euler,.quaternion
属性值是是四元数对象Quaternion
javascript// 绕着Y轴旋转90度 mesh.rotateY(Math.PI / 2); //控制台查看:旋转方法,改变了rotation属性 console.log(mesh.rotation);
- 代码演示html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>旋转平移缩放</title> <style> body { margin: 0; /* 隐藏body窗口区域滚动条 */ overflow: hidden; } </style> <script src="../../../../js/three.js"></script> <!-- 引入 three.ts 扩展控件 OrbitControls.js --> <script src="../../../../js/OrbitControls.js"></script> </head> <body> <script> /** * 创建场景对象Scene */ const scene = new THREE.Scene(); /** * 创建网格模型 */ const geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry const material = new THREE.MeshLambertMaterial({ color: 0x0000ff }); //材质对象Material const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh scene.add(mesh); //网格模型添加到场景中 // 网格模型xyz方向分别缩放0.5,1.5,2倍 // mesh.scale.set(0.5, 1.5, 2) // 直接设置网格模型的位置 // mesh.position.set(100, 100, 100) // 网格模型沿着x轴方向平移100 // mesh.translateX(100); //向量Vector3对象表示方向 // const axis = new THREE.Vector3(1, 1, 1); // axis.normalize(); //向量归一化 //沿着axis轴表示方向平移100 // mesh.translateOnAxis(axis, 100); // 绕着Y轴旋转90度 // mesh.rotateY(Math.PI / 2); // 绕axis轴旋转90度 // mesh.rotateOnAxis ( axis, Math.PI / 2 ) // console.log(mesh.rotation);//控制台查看:旋转方法,改变了rotation属性 // 辅助坐标系 const AxesHelper = new THREE.AxesHelper(250); scene.add(AxesHelper); /** * 光源设置 */ //点光源 const point = new THREE.PointLight(0xffffff); point.position.set(400, 200, 300); //点光源位置 scene.add(point); //点光源添加到场景中 //环境光 const ambient = new THREE.AmbientLight(0x444444); scene.add(ambient); /** * 相机设置 */ const width = window.innerWidth; //窗口宽度 const height = window.innerHeight; //窗口高度 const k = width / height; //窗口宽高比 const s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); camera.position.set(200, 300, 200); //设置相机位置 camera.lookAt(scene.position); //设置相机方向(指向的场景对象) /** * 创建渲染器对象 */ const renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height); //设置渲染区域尺寸 renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 document.body.appendChild(renderer.domElement); //body元素中插入canvas对象 // 渲染函数 function render() { renderer.render(scene, camera); //执行渲染操作 // mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度 requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧 } render(); //创建控件对象 相机对象camera作为参数 控件可以监听鼠标的变化,改变相机对象的属性 const controls = new THREE.OrbitControls(camera,renderer.domElement); //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果 // controls.addEventListener('change', render); </script> </body> </html>