自学内容网 自学内容网

3.js - 运动曲线

这个球,绕着这个红色的线圈转

在这里插入图片描述

代码


import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

let scene,
  camera,
  renderer,
  controls = null

let moon,
  earth = null

// 根据,一系列的点,创建曲线
let curve

const textureLoader = new THREE.TextureLoader()

const clock = new THREE.Clock()

const onWindowResize = () => {
// 重置相机的宽高比
camera.aspect = window.innerWidth / window.innerHeight
// 更新相机的投影矩阵
camera.updateProjectionMatrix()

// 重置渲染器的宽高比
renderer.setSize(window.innerWidth, window.innerHeight)
// 更新渲染器的像素比
renderer.setPixelRatio(window.devicePixelRatio)
}

const render = () => {
requestAnimationFrame(render)

const elapsed = clock.getElapsedTime()
let time = (elapsed /10) % 1
const point = curve.getPoint(time)
// console.log('point=', point) // Vector3 {x: -10, y: 0, z: 10}

// 情况一,moon绕着地球转
// moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5)

// 情况二,moon绕着咱画的线转
moon.position.copy(point)

// camera.position.copy(point)
// camera.lookAt(earth.position)

renderer.render(scene, camera)
}

const init = () => {
const EARTH_RADIUS = 1
const MOON_RADIUS = 0.27

scene = new THREE.Scene()

camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200)
// camera.position.set(0, 0, 3)
camera.position.set(0, 5, -10)
scene.add(camera)

const directionLight = new THREE.DirectionalLight(0xffffff) // 平行光
directionLight.position.set(0, 0, 1)
scene.add(directionLight)
const light = new THREE.AmbientLight(0xffffff, 0.5) // 环境光
scene.add(light)

// 添加地球
const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS, 16, 16)
const earthMaterial = new THREE.MeshPhongMaterial({
map: textureLoader.load('../public/assets/texture/planets/earth_atmos_2048.jpg'),
specularMap: textureLoader.load('../public/assets/texture/planets/earth_specular_2048.jpg'),
specular: 0x333333, // 高光部分的颜色,默认值:0x111111(深灰色)
shininess: 5, // 高光反射效果的锐利程度,该值越大,高光区域越小且更亮。默认值为30。
normalMap: textureLoader.load('../public/assets/texture/planets/earth_normal_2048.jpg'),
normalScale: new THREE.Vector2(0.85, 0.85)
})
earth = new THREE.Mesh(earthGeometry, earthMaterial)
scene.add(earth)

// 添加月球
const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS, 16, 16)
const moonMaterial = new THREE.MeshPhongMaterial({
map: textureLoader.load('../public/assets/texture/planets/moon_1024.jpg'),
shininess: 5
})
moon = new THREE.Mesh(moonGeometry, moonMaterial)
// moon.position.x = 3
scene.add(moon)

//-------------------------------------------------------------------------------

// 根据,一系列的点,创建曲线【参数true:表示曲线是封闭的】
curve = new THREE.CatmullRomCurve3([new THREE.Vector3(-10, 0, 10), new THREE.Vector3(-5, 5, 5), new THREE.Vector3(0, 0, 5), new THREE.Vector3(5, -5, 5), new THREE.Vector3(10, 0, 10)], true)

// 在曲线里,使用`getPoints()`,获取51个点
const points = curve.getPoints(600)
// console.log('points=', points) // 一个,包含600个Vector3元素的数组
const geometry = new THREE.BufferGeometry().setFromPoints(points)
const material = new THREE.LineBasicMaterial({ color: 0xff0000 })
const curveObject = new THREE.Line(geometry, material)
scene.add(curveObject)

//-------------------------------------------------------------------------------

renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

controls = new OrbitControls(camera, renderer.domElement)
controls.minDistance = 5 // 相机可以离目标对象的最小距离为5个单位(意味着,用户无法将相机拉得太近)
controls.maxDistance = 100 // 相机可以离目标对象的最大距离为100个单位(意味着,限制了用户可以将相机拉远的最大距离)

window.addEventListener('resize', onWindowResize)
}

init()
render()




原文地址:https://blog.csdn.net/pig_ning/article/details/142463421

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!