threeJS 自定义路径曲线(CatmullRomCurve3)

23 篇文章 2 订阅
18 篇文章 3 订阅

一、效果图

在这里插入图片描述

二、案例中用到的重要函数或设置

this.curve = new THREE.CatmullRomCurve3( [①
				    //起点
				    new THREE.Vector3(-10, 0, 10),
					 //中间节点
					new THREE.Vector3(-5,10,-10),
				    new THREE.Vector3(2, 5, -5),
				    //终点
				    new THREE.Vector3(10, 0, 10),
				  ],
				  true,
				);
				const geometry = new THREE.Geometry();②
				// 初始化曲线的顶点(放样点,数值越大弯曲更光滑)
				geometry.vertices = this.curve.getSpacedPoints(100);③

①:CatmullRomCurve3函数用来创建曲线,其中第一个点为起点,最后一个点为重点
CatmullRomCurve3(points,closed,curveType,tension)
points参数-----点数组
closed是否闭合,默认不闭合
curveType曲线类型
tension张力,默认0.5
②:THREE.Geometry()使用这个方法进行构造几何体的时候,需要使用 geometry.vertices 进行顶点设置。如果使用THREE.BufferGeometry(),则用setAttribute( ‘position’, new THREE.Float32BufferAttribute( vertices, 3 ) );进行设置顶点
③:getSpacedPoints()方法用来进行放样,数值越大生成的点数值越多,曲线就越光滑。

三、总体步骤

① 创建场景
② 创建相机
③创建渲染器
④ 创建物体

页面架构
<template>
	<div class="box4"></div>
</template>
<script>
</script>

<style>
</style>

导入文件,创建变量和函数
	import * as THREE from 'three';
	import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
	import Stats from 'three/examples/jsm/libs/stats.module';
		export default{
		name:"box2",
		data(){
			return{
			urn{
				scene:null,
				camera:null,
				renderer:null,
				stats:null,
				pointLight:null,
				pos:0,
				curve:null,
				sphereLightMesh:null,
				]
			}
		},
			methods:{
		     init(){
		     },
				run(){
			
			},
			onResize(){
			
			}
		},
       mounted() {
       	    
       }
       }

①创建场景

init函数中

this.scene=new THREE.Scene();//创建场景
②创建相机

init函数中

				this.camera=new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,1000);//创建相机
				this.camera.position.set(0,70,70);//设置相机位置
				this.camera.lookAt(new THREE.Vector3(0,0,0));//设置相机关注点
③创建渲染器

init函数中

this.renderer=new THREE.WebGLRenderer({antialias:true});//创建渲染器,并打开反锯齿
				this.renderer.setSize(window.innerWidth,window.innerHeight);//设置渲染的尺寸
				this.renderer.setClearColor(0x000000);//设置颜色
				this.renderer.setPixelRatio(window.devicePixelRatio);
				this.stats=new Stats();
				let control=new OrbitControls(this.camera,this.renderer.domElement);
				
				//挂载
				document.getElementsByClassName("box4")[0].appendChild(this.stats.domElement);
				document.getElementsByClassName("box4")[0].appendChild(this.renderer.domElement);
				window.addEventListener("resize",this.onSize,false);//添加监听事件

onResize函数中

onSize(){
				this.camera.aspect=window.innerWidth/window.innerHeight;
				this.renderer.setSize(window.innerWidth,window.innerHeight);
				this.camera.updateProjectionMatrix();
			}

run函数中

run(){
				requestAnimationFrame(this.run);
				
				let pointLight=this.scene.getObjectByName("pointLight");
				if(this.pos<1){
					pointLight.position=this.curve.getPointAt(this.pos);//光移动
					this.sphereLightMesh.position.copy(pointLight.position);//物体跟着光移动
					this.pos+=0.001;
				}else{
					this.pos=0;
				}
				
				this.renderer.render(this.scene,this.camera);
				this.stats.update();
			},
④创建物体

init函数中

				this.scene.add(new THREE.AxesHelper(20));//添加辅助函数
				this.pointLight=new THREE.PointLight(0xffffff);
				this.pointLight.position.set(0,5,5);
				this.pointLight.name="pointLight";//给灯光命名,用于后期获取灯光对象
				this.scene.add(this.pointLight);
				//创建灯
				let sphereLight=new THREE.SphereGeometry(0.5,50,50);
				let spLightMaterial=new THREE.MeshLambertMaterial({
					 color:0xffffff,
					 emissive:0xffffff
				})
				this.sphereLightMesh=new THREE.Mesh(sphereLight,spLightMaterial);
				this.sphereLightMesh.position.copy(this.pointLight.position);
				this.scene.add(this.sphereLightMesh);
				//创建物体
				let spheregeo=new THREE.SphereGeometry(5,100,100);
				let sphereMaterial=new THREE.MeshLambertMaterial({
					 color:new THREE.Color().setHSL(Math.random(),0.5,0.5),
				})
				this.scene.add(new THREE.Mesh(spheregeo,sphereMaterial));
				this.curve = new THREE.CatmullRomCurve3( [
				    //起点
				    new THREE.Vector3(-10, 0, 10),
					 //中间节点
					new THREE.Vector3(-5,10,-10),
				    new THREE.Vector3(2, 5, -5),
				    //终点
				    new THREE.Vector3(10, 0, 10),
				  ],
				  true,
				);
				 console.log(this.curve.getPoint( 0.1 ));
				// 绘制曲线
				let geometry = new THREE.Geometry();
				// 初始化曲线的顶点(放样点,数值越大弯曲更光滑)
				geometry.vertices = this.curve.getSpacedPoints(100);
				let material = new THREE.LineBasicMaterial({ color:new THREE.Color().setHSL(Math.random(),0.5,0.5) });
				let curveObject = new THREE.Line(geometry, material);
				this.scene.add(curveObject);

四、总代码

<template>
	<div class="box4"></div>
</template>

<script>
	import * as THREE from 'three';
	import Stats from 'three/examples/jsm/libs/stats.module';
	import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
	export default{
		data(){
			return{
				scene:null,
				camera:null,
				renderer:null,
				stats:null,
				pointLight:null,
				pos:0,
				curve:null,
				sphereLightMesh:null,
			}
		},
		methods:{
			init(){
				this.scene=new THREE.Scene();//创建场景
				this.camera=new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,1000);//创建相机
				this.camera.position.set(0,70,70);//设置相机位置
				this.camera.lookAt(new THREE.Vector3(0,0,0));//设置相机关注点
				
				this.scene.add(new THREE.AxesHelper(20));//添加辅助函数
				this.pointLight=new THREE.PointLight(0xffffff);
				this.pointLight.position.set(0,5,5);
				this.pointLight.name="pointLight";//给灯光命名,用于后期获取灯光对象
				this.scene.add(this.pointLight);
				//创建灯
				let sphereLight=new THREE.SphereGeometry(0.5,50,50);
				let spLightMaterial=new THREE.MeshLambertMaterial({
					 color:0xffffff,
					 emissive:0xffffff
				})
				this.sphereLightMesh=new THREE.Mesh(sphereLight,spLightMaterial);
				this.sphereLightMesh.position.copy(this.pointLight.position);
				this.scene.add(this.sphereLightMesh);
				//创建物体
				let spheregeo=new THREE.SphereGeometry(5,100,100);
				let sphereMaterial=new THREE.MeshLambertMaterial({
					 color:new THREE.Color().setHSL(Math.random(),0.5,0.5),
				})
				this.scene.add(new THREE.Mesh(spheregeo,sphereMaterial));
				this.curve = new THREE.CatmullRomCurve3( [
				    //起点
				    new THREE.Vector3(-10, 0, 10),
					 //中间节点
					new THREE.Vector3(-5,10,-10),
				    new THREE.Vector3(2, 5, -5),
				    //终点
				    new THREE.Vector3(10, 0, 10),
				  ],
				  true,
				);
				 console.log(this.curve.getPoint( 0.1 ));
				// 绘制曲线
				let geometry = new THREE.Geometry();
				// 初始化曲线的顶点(放样点,数值越大弯曲更光滑)
				geometry.vertices = this.curve.getSpacedPoints(100);
				let material = new THREE.LineBasicMaterial({ color:new THREE.Color().setHSL(Math.random(),0.5,0.5) });
				let curveObject = new THREE.Line(geometry, material);
				this.scene.add(curveObject);
				
				
				this.renderer=new THREE.WebGLRenderer({antialias:true});//创建渲染器,并打开反锯齿
				this.renderer.setSize(window.innerWidth,window.innerHeight);//设置渲染的尺寸
				this.renderer.setClearColor(0x000000);//设置颜色
				this.renderer.setPixelRatio(window.devicePixelRatio);
				this.stats=new Stats();
				let control=new OrbitControls(this.camera,this.renderer.domElement);
				
				//挂载
				document.getElementsByClassName("box4")[0].appendChild(this.stats.domElement);
				document.getElementsByClassName("box4")[0].appendChild(this.renderer.domElement);
				window.addEventListener("resize",this.onSize,false);//添加监听事件
			},
			run(){
				requestAnimationFrame(this.run);
				
				let pointLight=this.scene.getObjectByName("pointLight");
				if(this.pos<1){
					pointLight.position=this.curve.getPointAt(this.pos);//光移动
					this.sphereLightMesh.position.copy(pointLight.position);//物体跟着光移动
					this.pos+=0.001;
				}else{
					this.pos=0;
				}
				
				this.renderer.render(this.scene,this.camera);
				this.stats.update();
			},
			onSize(){
				this.camera.aspect=window.innerWidth/window.innerHeight;
				this.renderer.setSize(window.innerWidth,window.innerHeight);
				this.camera.updateProjectionMatrix();
			}
		},
		mounted() {
			this.init();
			this.run();
		}
	}
</script>

<style>
</style>

五:GitHub 地址

https://github.com/supremeliuao/kh-csdn-project.git(别忘sta,小伙伴们)

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kinghiee

爸爸们求打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值