【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)
相关推荐
老兵发新帖4 分钟前
pnpm 与 npm 的核心区别
前端·npm·node.js
超级土豆粉5 分钟前
怎么打包发布到npm?——从零到一的详细指南
前端·npm·node.js
OpenTiny社区10 分钟前
TinyEngine 2.5版本正式发布:多选交互优化升级,页面预览支持热更新,性能持续跃升!
前端·低代码·开源·交互·opentiny
声声codeGrandMaster32 分钟前
Django框架的前端部分使用Ajax请求一
前端·后端·python·ajax·django
重生之后端学习2 小时前
02-前端Web开发(JS+Vue+Ajax)
java·开发语言·前端·javascript·vue.js
繁依Fanyi3 小时前
用 CodeBuddy 实现「IdeaSpark 每日灵感卡」:一场 UI 与灵感的极简之旅
开发语言·前端·游戏·ui·编辑器·codebuddy首席试玩官
来自星星的坤5 小时前
【Vue 3 + Vue Router 4】如何正确重置路由实例(resetRouter)——避免“VueRouter is not defined”错误
前端·javascript·vue.js
香蕉可乐荷包蛋9 小时前
浅入ES5、ES6(ES2015)、ES2023(ES14)版本对比,及使用建议---ES6就够用(个人觉得)
前端·javascript·es6
未来之窗软件服务10 小时前
资源管理器必要性———仙盟创梦IDE
前端·javascript·ide·仙盟创梦ide
liuyang___10 小时前
第一次经历项目上线
前端·typescript