首页 > 其他分享 >【Three.JS零基础入门教程】第四篇:基础变换

【Three.JS零基础入门教程】第四篇:基础变换

时间:2024-08-15 10:24:38浏览次数:9  
标签:10 cube const 入门教程 THREE Three add new JS

前期回顾:

【Three.JS零基础入门教程】第一篇:搭建开发环境

【Three.JS零基础入门教程】第二篇:起步案例

【Three.JS零基础入门教程】第三篇:开发辅助

接下来, 我们通过三种基础的变换来加深对3D坐标系中坐标单位的理解, 同时也是动画的基础. 分别是:

  • 移动
  • 缩放
  • 旋转
效果

动图封面

1. 网络辅助工具

为了更好的理解坐标单位, 我们引入网格辅助工具(GridHelper)

// 5. 创建立方体(几何+材质)
const cubeGeometry = new THREE.BoxGeometry(2, 2, 2)
const cubeMaterial = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)

// 创建网格辅助工具
const gridHelper = new THREE.GridHelper( 20, 20, 0xffffff, 0xffffff )
// 为了更方便观察, 设置opacity透明度
gridHelper.material.transparent = true
gridHelper.material.opacity = 0.5

// 添加到场景中
scene.add( gridHelper )
  1. 为了方便观察, 我们把立方体的大小改成了(2,2,2). 这种x轴的范围为(-1, 1)
  2. 创建网格辅助工具, 并添加到场景中
    1. 第一个参数(size): 网格的总宽高, 设置为20, 对应x轴的坐标范围为(-10, 10), 默认值为10
    2. 第二个参数(divisions): 网格分成多少份, 设置为20, 每份就是1个单位, 默认值为10
    3. 第三个参数(colorCenterLine): 中线的颜色, 默认值为0x444444
    4. 第四个参数(colorGrid): 网络线的颜色, 默认值为0x888888

2. 移动

通过改变物体的position属性, 控制物体的移动

// 通过设置三维向量的属性控制移动
cube.position.x = 2
cube.position.y = 2
cube.position.z = 2
// 通过调用三维向量的方法控制移动
cube.position.set(3, 3, 3)
// 添加到场景
scene.add(cube)

通过设置cube的position(三维向量)对象的x, y, z的值来控制立方体分别沿x, y, z轴移动

3. 缩放

通过改变物体的scale属性, 控制物体的缩放

// 通过设置三维向量的属性控制缩放比例
cube.scale.x = 1
cube.scale.y = 2
cube.scale.z = 3
// 通过调用三维向量的方法控制缩放
cube.scale.set(3, 3, 3)

4. 旋转

通过改变物体的rotation属性, 控制物体的旋转.

这里需要注意的是: 旋转的单位是弧度, 不是角度

换算公式

π弧度 = 180度

  • 弧度=角度×(π ÷ 180)
  • 角度=弧度×(180 ÷ π)

常用弧度

π/2弧度 = 90度

π/3弧度 = 60度

π/4弧度 = 45度

π/6弧度 = 30度

按照右手法则, 大拇指指向x轴, 四指方向为正方向, 即从x轴方向观察, 逆时间旋转

// 通过设置三维向量的属性控制旋转
cube.rotation.x = Math.PI / 4
// 通过三维向量的方法控制旋转
cube.rotation.set(Math.PI / 4, 0, 0)

5. 集成Gui工具

我们发现, 如果每次通过修改代码的方式修改属性值效率太低

这里我们可以集成一种Gui工具, 通过UI交互界面来修改方便很多

dat.gui的npm链接

1) 安装

npm i dat.gui

2) 基本使用

// 导入dat
import * as dat from 'dat.gui'
// 初始化
const gui = new dat.GUI()
gui.add(cube.position, 'x').min(-10).max(10).step(1)

这里我们可以做一个分组

// 5. 创建立方体(几何+材质)
const cubeGeometry = new THREE.BoxGeometry(2, 2, 2)
const cubeMaterial = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)

const gui = new dat.GUI()
const guiPosition = gui.addFolder('移动')
guiPosition.add(cube.position, 'x').min(-10).max(10).step(1)
guiPosition.add(cube.position, 'y').min(-10).max(10).step(1)
guiPosition.add(cube.position, 'z').min(-10).max(10).step(1)

const guiScale = gui.addFolder('缩放')
guiScale.add(cube.scale, 'x').min(1).max(10).step(1)
guiScale.add(cube.scale, 'y').min(1).max(10).step(1)
guiScale.add(cube.scale, 'z').min(1).max(10).step(1)

const guiRotate = gui.addFolder('旋转(度)')
const data = {
  x: 0,
  y: 0,
  z: 0,
}
guiRotate.add(data, 'x', -180, 180, 1).onChange((value) => {
  // 在onChange的回调中
  //  1. 通过形参获取修改的数值
  //  2. 使用THREE提供的数学工具, 将 度 转换成 弧度
  cube.rotation.x = THREE.MathUtils.degToRad(value)
})
guiRotate.add(data, 'y', -180, 180, 1).onChange((value) => {
  cube.rotation.y = THREE.MathUtils.degToRad(value)
})
guiRotate.add(data, 'z', -180, 180, 1).onChange((value) => {
  cube.rotation.z = THREE.MathUtils.degToRad(value)
})

完整示例:

// 导入three.js
import * as THREE from 'three'

import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 导入dat.gui
import * as dat from 'dat.gui'

// 1. 创建场景
const scene = new THREE.Scene()

// 5. 创建立方体(几何+材质)
const cubeGeometry = new THREE.BoxGeometry(2, 2, 2)
const cubeMaterial = new THREE.MeshNormalMaterial()
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)

scene.add(cube)

// 集成Gui工具
const gui = new dat.GUI()
/**
 * 添加一个配置项
 * @param Object
 * @param Attr
 */
const guiPosition = gui.addFolder('位置信息')
guiPosition.add(cube.position, 'x', -10, 10, 1)
guiPosition.add(cube.position, 'y', -10, 10, 1)
guiPosition.add(cube.position, 'z', -10, 10, 1)

const guiScale = gui.addFolder('缩放')
guiScale.add(cube.scale, 'x', 1, 10, 1)
guiScale.add(cube.scale, 'y', 1, 10, 1)
guiScale.add(cube.scale, 'z', 1, 10, 1)

const guiRotate = gui.addFolder('旋转(度)')
const data = {
  x: 0,
  y: 0,
  z: 0,
}
guiRotate.add(data, 'x', -180, 180, 1).onChange((value) => {
  // 在onChange的回调中
  //  1. 通过形参获取修改的数值
  //  2. 使用THREE提供的数学工具, 将 度 转换成 弧度
  cube.rotation.x = THREE.MathUtils.degToRad(value)
})
guiRotate.add(data, 'y', -180, 180, 1).onChange((value) => {
  // 在onChange的回调中
  //  1. 通过形参获取修改的数值
  //  2. 使用THREE提供的数学工具, 将 度 转换成 弧度
  cube.rotation.y = THREE.MathUtils.degToRad(value)
})
guiRotate.add(data, 'z', -180, 180, 1).onChange((value) => {
  // 在onChange的回调中
  //  1. 通过形参获取修改的数值
  //  2. 使用THREE提供的数学工具, 将 度 转换成 弧度
  cube.rotation.z = THREE.MathUtils.degToRad(value)
})

// 2. 创建相机
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight,
  1,
  1000
)
camera.position.set(20, 20, 20)
camera.lookAt(0, 0, 0)

// 6. 创建坐标轴的辅助对象
const axesHelper = new THREE.AxesHelper(10)
scene.add(axesHelper)

// 创建网格辅助对象
const gridHelper = new THREE.GridHelper(20, 20, 0xffffff, 0xffffff)
gridHelper.material.transparent = true
gridHelper.material.opacity = 0.5
scene.add(gridHelper)

// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setAnimationLoop(animation)
document.body.appendChild(renderer.domElement)

// 4. 渲染
function animation() {
  renderer.render(scene, camera)
}

// 7. 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)

// 8. 监听window的resize事件
window.addEventListener('resize', () => {
  // 重新设置相机的宽高比
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()

  // 设置渲染器的出图(照片的大小)
  renderer.setSize(window.innerWidth, window.innerHeight)
})

需要视频教程的,可以点击下方卡片备注【threejs】

GIS资料免费获取icon-default.png?t=N7T8https://www.wjx.cn/vm/wRqdSxO.aspx# 

标签:10,cube,const,入门教程,THREE,Three,add,new,JS
From: https://blog.csdn.net/2401_84715637/article/details/141215587

相关文章

  • 基于SpringBoot+MySQL+SSM+Vue.js的药房药品采购系统(附论文)
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基于SpringBoot+MySQL+SSM+Vue.js的药房药品采购系统(附论文......
  • 基于SpringBoot+MySQL+SSM+Vue.js的旅游咨询系统
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基于SpringBoot+MySQL+SSM+Vue.js的旅游咨询系统,用户,管理......
  • JS脚本内追加的标签无法触发事件问题处理
    通过JS追加的标签无法触发事件时,就把事件挂载给这个标签父级标签,如下。//后追加标签事件不生效,挂载在父级标签varparentElement=document.getElementById('layout_detail_toolbar_0');parentElement.addEventListener('change',function(event){letta......
  • 使用 TypeScript 在 React JS 中进行路由
    一.介绍单页应用程序(SPA)中的路由支持在视图之间导航,而无需重新加载应用程序。ReactRouter是React应用程序中路由的标准库。本文简要概述了使用TypeScript设置路由的方法。二.设置项目创建一个新的React项目npxcreate-react-appreact-router-ts--template......
  • java语言,MySQL数据库;电影推荐网站 30760(免费领源码)计算机毕业设计项目推荐万套实战教
    摘 要随着互联网时代的到来,同时计算机网络技术高速发展,网络管理运用也变得越来越广泛。因此,建立一个B/S结构的电影推荐网站;电影推荐网站的管理工作系统化、规范化,也会提高平台形象,提高管理效率。本电影推荐网站是针对目前电影推荐网站的实际需求,从实际工作出发,对过去的电影......
  • java语言,MySQL数据库;基于Web的高校知识共享系统设计与实现 32050(免费领源码)计算机毕业
    摘 要信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对高校知识共享系统等问题,对高校知识共享系统进行研究分析,然后开发设计出高校知识共享系统以......
  • java语言,MySQL数据库;23825基于java的员工考勤系统(免费领源码)计算机毕业设计项目推荐万
    摘 要由于数据库和数据仓库技术的快速发展,员工考勤系统建设越来越向模块化、智能化、自我服务和管理科学化的方向发展。考勤管理系统对处理对象和服务对象,自身的系统结构,处理能力,都将适应技术发展的要求发生重大的变化。员工考勤系统除了具有共享系统的全部功能以外,能通过......
  • JS贪吃蛇
    1.整个简洁版的贪吃蛇完整代码,后面会解析<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>贪吃蛇</title></head><bodystyle="height:90vh;display:flex;justify-content:center;align-items:center;......
  • SMHC Three SD/MMC host controller (SMHC) interfaces
    SMHCThreeSD/MMChostcontroller(SMHC)interfaces1TheSMHC0controlsthedevicesthatcomplywiththeprotocolSecureDigitalMemory(SDmem-version3.0)2TheSMHC1controlsthedevicethatcomplieswiththeprotocolSecureDigitalI/O(SDIO-version......
  • C#基础:JSON和字符串、字典、实体类的相互转化方案
    备注:可直接在控制台输出,不需要引用第三方nuget包usingSystem;usingSystem.Collections.Generic;usingSystem.Text.Encodings.Web;usingSystem.Text.Json;classProgram{publicclassData{publicstringMoCategorySelect{get;set;}......