【ThreeJS Basics 1-4】变换物体 VIP

@[TOC]


概述

有常用的四种维度,用来变换物体

  • 位置 position
  • 旋转 rotation
  • 缩放 scale
  • 四元数 quaternion

再此之前引入一个 Axes Helper 用于帮我们更好的观察物体的变换


Axes helper 帮助轴

这个是官网的说明

在场景中添加一个 轴 Helper,(我也不知道怎么翻译好了) ,然后移动一下相机的位置,可以看到三个轴都能显示出来

也可以填写数字来改变轴的长度

js 复制代码
import * as THREE from 'three'

// Canvas
const canvas = document.querySelector('canvas.webgl')

// Scene
const scene = new THREE.Scene()

/**
 * Axes Helper
 */
const axesHelper = new THREE.AxesHelper(2)
scene.add(axesHelper)

/**
 * Sizes
 */
const sizes = {
    width: 800,
    height: 600
}

/**
 * Camera
 */
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z = 3
camera.position.y = 0.5
camera.position.x = 0.5

// camera.lookAt(new THREE.Vector3(0, - 1, 0))
scene.add(camera)

/**
 * Renderer
 */
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.render(scene, camera)

Position 位置的变换

所有物体添加到场景,如果不声明位置的话,默认都是原点,也就是 (0,0,0),所以,当你把帮助轴,相机都添加到场景时

如果没有调整相机的位置,可能你也看不到轴,或者疑惑为什么只能看到两个轴

变换可以生效的情况

通常情况下,声明这些变换,需要在渲染前完成

这也很好理解,渲染就像相机的拍照快门一样,拍照后在移动位置的话,肯定不会呈现在照片上了

物体到场景中心的距离

直接使用 物体.position.length(),这个方法即可,公式为

<math xmlns="http://www.w3.org/1998/Math/MathML"> 距离 = x 2 + y 2 + z 2 \text{距离} = \sqrt{x^2 + y^2 + z^2} </math>距离=x2+y2+z2

js 复制代码
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z = 6
camera.position.y = 3
camera.position.x = 2
console.log('获取相机到场景中心位置的长度:>>', camera.position.length())

物体A到物体B的距离

这个也是会用到的,跟上面的方法类似,不过要知道传递的是 Vector3 类型的向量

js 复制代码
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z = 6
camera.position.y = 3
camera.position.x = 2
console.log('获取相机到场景中心位置的长度:>>', camera.position.length())
console.log('获取相机到(0,1,2)长度:>>', camera.position.distanceTo(new THREE.Vector3(0, 1, 2)))
console.log('获取相机到cube1的长度:>>', camera.position.distanceTo(cube1.position))

Position.set()

这个方法也是设置位置的

js 复制代码
camera.position.x = 2
camera.position.y = 3
camera.position.z = 6

camera.position.set(2, 3, 7)

Scale 缩放

缩放的效果如下图所示

js 复制代码
cube1.scale.x = 2
cube1.scale.y = 3
cube1.scale.z = .5
cube1.scale.set(1, 1, 1)

rotate 旋转

js 复制代码
cube1.scale.set(2, .5, 4)

cube1.rotation.reorder("YXZ")
cube1.rotation.x = 0
cube1.rotation.y = 0
cube1.rotation.z = Math.PI / 2

旋转的时候需要小心,关于旋转的顺序问题,此时就需要声明好顺序 cube1.rotation.reorder("YXZ")

Quaternion 四元数

为了解决上面旋转的问题,引入四元数 为了更数学的表示旋转 具体是怎么玩的,这是个数学问题,比较庞大,不过它会吐出一个类似向量的四维数组,获取它并且使用它就可以正确的旋转,避免万向锁了。

Camera lookat 相机聚焦

js 复制代码
// camera.lookAt(new THREE.Vector3(0, - 1, 0))
camera.lookAt(cube1.position)

Group 组

组是为了解决创建复杂的集合体,可以批量的进行位置改变,缩放,以及旋转

js 复制代码
/**
 * Objects
 */
const group = new THREE.Group()
// group.scale.y = 1
// group.rotation.y = 0.2
scene.add(group)

const cube1 = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0xff0000 })
)
group.add(cube1)

const cube2 = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0x00ff00 })
)
cube2.position.x = 1.5
group.add(cube2)

const cube3 = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0x0000ff })
)
cube3.position.x = -1.5
group.add(cube3)
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪10 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试