当前位置:网站首页>threejs:两点坐标绘制贝赛尔曲线遇到的坑
threejs:两点坐标绘制贝赛尔曲线遇到的坑
2022-06-11 00:26:00 【粉末的沉淀】
飞机从武汉飞往背景,根据起点和终点,需要绘制飞机航线,网上搜来的通用代码运行后一直找不到copy属性。
坑1:
ray的at方法参数变更:
仔细排查发现,是ray的at方法修改了,现在必须要两个参数了,只需要增加一个临时变量来充当at方法的target 参数,只需要修改一点点就可以了。

坑2:
并非所有的起点和终点都可以绘制贝塞尔曲线:
代码跑通后,我随便设置了如下图的一组起点和终点,结果绘制的是一条直线。

v0和v3设置成下图,甚至还报NAN的错!


直到我把v0和v3设置得更加随机一些,才终于出现了曲线!

总结一下两点绘制贝塞尔曲线的方法:
创建一条平滑的三维 三次贝塞尔曲线, 由起点、终点和两个控制点所定义。
但是基于我们日常的需求,比如飞机航线,我们只知道起点和终点,也就是v0和v3,所以我们需要通过一系列算法,得到中间的两个控制点,也就是v1和v2,但是v0和v3需要符合一定条件,目前我通过经验,只能找到两个反例:
1、 v0和v3不可以是原点,也就是坐标不能为(0,0,0),否则绘制出来的将是一条直线。
2、v0和v3组成的直线,不可以贴在一条轴线上,比如(-5,0,0)和(5,0,0),就是一条贴在x轴的直线,这样我们的算法会报NaN的错。
既然如此,那就让v0和v3随机一点吧。
修改后的js代码如下:
import * as THREE from 'three'
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js';
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js';
import { Line2 } from 'three/examples/jsm/lines/Line2.js';
export function createFlyLine( v0, v3 ) {
// 夹角
var angle = ( v0.angleTo( v3 ) * 1.8 ) / Math.PI / 0.1; // 0 ~ Math.PI
var aLen = angle * 0.4, hLen = angle * angle * 12;
var p0 = new THREE.Vector3( 0, 0, 0 );
// 法线向量
var rayLine = new THREE.Ray( p0, getVCenter( v0.clone(), v3.clone() ) );
// ray的at方法现在必须要两个参数才能执行,所以需要加入临时变量temp
var temp = new THREE.Vector3();
// 顶点坐标
var vtop = rayLine.at( hLen / rayLine.at( 1,temp).distanceTo( p0 ),temp);
// 控制点坐标
var v1 = getLenVcetor( v0.clone(), vtop, aLen );
var v2 = getLenVcetor( v3.clone(), vtop, aLen );
// 绘制三维三次贝赛尔曲线
var curve = new THREE.CubicBezierCurve3( v0, v1, v2, v3 );
var geometry = new LineGeometry();
var points = curve.getSpacedPoints( 5000 );
var positions = [];
var colors = [];
var color = new THREE.Color();
/**
* HSL中使用渐变
* h — hue value between 0.0 and 1.0
* s — 饱和度 between 0.0 and 1.0
* l — 亮度 between 0.0 and 1.0
*/
for (var j = 0; j < points.length; j ++) {
// color.setHSL( .31666+j*0.005,0.7, 0.7); //绿色
color.setHSL( .81666+j,0.88, 0.715+j*0.0025); //粉色
colors.push( color.r, color.g, color.b );
positions.push( points[j].x, points[j].y, points[j].z );
}
geometry.setPositions( positions );
geometry.setColors( colors );
var matLine = new LineMaterial( {
linewidth: 0.0006,
vertexColors: true,
dashed: false
} );
var lineMesh = new Line2( geometry, matLine );
return lineMesh;
}
// 计算v1,v2 的中点
function getVCenter( v1, v2 ) {
const v = v1.add( v2 );
return v.divideScalar( 2 );
}
// 计算V1,V2向量固定长度的点
function getLenVcetor( v1, v2, len ) {
const v1v2Len = v1.distanceTo( v2 );
return v1.lerp( v2, len / v1v2Len );
}
vue代码如下:
<template>
<div>
<!-- 本案例演示两点绘制贝塞尔曲线-->
<div id="container"></div>
</div>
</template>
<script>
import * as THREE from 'three'
// 注意OrbitControls要加{},注意路径是jsm
import {
OrbitControls
} from 'three/examples/jsm/controls/OrbitControls.js';
import {
createFlyLine,timerFlyLine
} from './flyLine.js';
export default {
name: "hello",
props: {
},
components: {
},
data() {
return {
scene: null,
renderer: null,
camera: null,
orbitControls: null
}
},
created() {},
mounted() {
this.init();
this.animate();
},
//后续还要在beforeDestory中进行销毁
beforeDestroy() {
this.scene = null;
this.renderer = null;
this.camera = null;
this.orbitControls = null;
clearInterval(timerFlyLine);
},
methods: {
// 场景初始化
init() {
let container = document.getElementById('container');
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 特别注意,相机的位置要大于几何体的尺寸
this.camera.position.x = 10;
this.camera.position.y = 10;
this.camera.position.z = 10;
this.scene = new THREE.Scene();
this.renderer = new THREE.WebGLRenderer({
// alpha: true, // canvas是否包含alpha (透明度) 默认为 false
antialias: true,
// precision: 'highp',
})
// this.renderer.setClearAlpha(0.0); // 设置alpha,合法参数是一个 0.0 到 1.0 之间的浮点数
// 设置背景色
this.renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(this.renderer.domElement);
// 添加三维坐标轴
// 红色代表x轴,绿色代表y轴,蓝色代表z轴
// let axesHelper = new THREE.AxesHelper(30);
// this.scene.add(axesHelper);
// 环境光不能用来投射阴影,因为它没有方向。
var ambienLight = new THREE.AmbientLight(0xcccccc);
this.scene.add(ambienLight);
// 初始化轨道控制器
// 还需要配合animate,不断循环渲染,达到用鼠标旋转物体的作用。
this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);
// 窗口大小自适应
window.addEventListener('resize', this.onWindowResize, false);
this.addObjects();
},
// 添加物体
addObjects(){
// var v0 = new THREE.Vector3(-3, 4, 0);
// var v3 = new THREE.Vector3(3, 4, 0);
var v0 = new THREE.Vector3(- 1.7049594735603837, 3.208354470512221, - 3.4350509144786985);
var v3 = new THREE.Vector3(0.5738958419746141, - 0.44114968930852216, 4.9473255920938985);
var sphere = createFlyLine(v0,v3);
this.scene.add(sphere);
},
animate() {
requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera);
},
onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
}
}
}
</script>
<style scoped>
#container {
width: 100%;
height: 600px;
outline: none;
/* background-image: linear-gradient(rgb(255, 255, 255), rgb(119, 119, 237)); */
}
</style>
边栏推荐
- 【ROS】ROSmsg cakin_ Make compilation error
- Introduction to China patent award policy support, with a subsidy of 1million yuan
- Time dependent - format, operation, comparison, conversion
- Web3生态去中心化金融平台——Sealem Finance
- 北京門頭溝區高新技術企業培育支持標准,補貼10萬
- Beijing Fangshan District high tech enterprise cultivation support standard, with a subsidy of 100000 yuan
- IRS application release 16: H5 application design guide
- 百万级访问量—高并发问题的解决历程
- Merge sort and cardinality sort
- Norme de soutien à la culture des entreprises de haute technologie du district de Mentougou à Beijing, subvention de 100 000 RMB
猜你喜欢

Multi interest recall model practice | acquisition technology

Yunna Qingyuan fixed assets management and barcode inventory system

中间件_Redis_06_Redis的事务

Understanding of multithreading

Basic introduction of graph and depth first traversal and breadth first traversal

简述自定义注解

Brief description of custom annotations

Web3 ecological decentralized financial platform sealem Finance

SAS discriminant analysis (Bayes criterion and proc discrim process)

Yunna provincial administrative unit fixed assets management system
随机推荐
Support standard for cultivation of high-tech enterprises in Miyun District, Beijing, with a subsidy of 100000 yuan
nodejs中使用mySql数据库
云呐|省级行政单位固定资产管理系统
Introduction to the application process of China Patent Award, with a subsidy of 1million yuan
Norme de soutien à la culture des entreprises de haute technologie du district de Mentougou à Beijing, subvention de 100 000 RMB
Multi interest recall model practice | acquisition technology
2022 recognition requirements for new technologies and new products (services) in Huairou District, Beijing
Introduction to China patent award policy support, with a subsidy of 1million yuan
Clean up the broken artifacts data (.lastUpdated files) and reload the project. Problem resolution
北京门头沟区高新技术企业培育支持标准,补贴10万
1.4PX4程序下载
Introduction to support standards for specialized, special and new manufacturing enterprises in Chaoyang District, Beijing, with a subsidy of 1million yuan
Millions of visits - resolution of high concurrency problems
对多线程的理解
Beijing Yanqing District high tech enterprise cultivation support standard, with a subsidy of 100000 yuan
How to write this with data and proc without SQL
记录打包GoogleChrome浏览器插件
How to use user-defined annotation for parameter verification
How much is the bonus of China Patent Award, with a subsidy of 1million yuan
SAS因子分析(proc factor过程和因子旋转以及回归法求因子得分函数)