当前位置:网站首页>Threejs: pit encountered in drawing Bessel curve with two-point coordinates

Threejs: pit encountered in drawing Bessel curve with two-point coordinates

2022-06-11 01:41:00 Precipitation of powder

The plane flew from Wuhan to the background , According to the starting point and the end point , Need to draw aircraft route , General code found on the Internet Can't find... After running copy attribute .

pit 1:

ray Of at Method parameter change :

Careful investigation revealed that , yes ray Of at Methods to modify 了 , Now you have to take two parameters , Just add a temporary variable to act as at Methodical target Parameters , It only needs a little modification .

pit 2:

Not all start and end points can be plotted with Bezier curves :

After the code runs through , I randomly set a set of start and end points as shown in the figure below , The result is a straight line .

v0 and v3 Set to the following figure , Even reported NAN The fault of !

  Until I put it v0 and v3 Set it more randomly , Only then finally appeared the curve !

 

Summarize the method of drawing Bezier curve at two points :

Create a smooth 3D   Three Bessel curves , From the starting point 、 End point and two control points .

But based on our daily needs , For example, aircraft routes , We only know the beginning and the end , That is to say v0 and v3, So we need a series of algorithms , Get the two control points in the middle , That is to say v1 and v2, however v0 and v3 It needs to meet certain conditions , At present, I pass the experience , Only two counterexamples can be found :

1、 v0 and v3 It cannot be the origin , That is, the coordinates cannot be (0,0,0), Otherwise, a straight line will be drawn .

2、v0 and v3 Composed of straight lines , Do not stick it on an axis , such as (-5,0,0) and (5,0,0), It's just a piece posted on x Axis line , So our algorithm will report NaN The fault of .

In that case , Then let's v0 and v3 Be a little random .

The modified js The code is as follows :

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 ) {
	
		//  Angle 
		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 );
		//  Normal vector 
		var rayLine = new THREE.Ray( p0, getVCenter( v0.clone(), v3.clone() ) );
		// ray Of at Method now requires two arguments to execute , So you need to add temporary variables temp
		var temp = new THREE.Vector3();
		//  Vertex coordinates 
		var vtop = rayLine.at( hLen / rayLine.at( 1,temp).distanceTo( p0 ),temp);
		//  Control point coordinates 
		var v1 = getLenVcetor( v0.clone(), vtop, aLen );
		var v2 = getLenVcetor( v3.clone(), vtop, aLen );
		//  Draw three-dimensional cubic Bessel curve 
		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 Use gradients in 
		 * h — hue value between 0.0 and 1.0
		 * s —  saturation  between 0.0 and 1.0
		 * l —  brightness  between 0.0 and 1.0
		 */
		for (var j = 0; j < points.length; j ++) {
			// color.setHSL( .31666+j*0.005,0.7, 0.7); // green 
			color.setHSL( .81666+j,0.88, 0.715+j*0.0025); // Pink 
			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;
}
//  Calculation v1,v2  The midpoint of 
	function getVCenter( v1, v2 ) {
		const v = v1.add( v2 );
		return v.divideScalar( 2 );
	}

	//  Calculation V1,V2 Vector fixed length point 
	function getLenVcetor( v1, v2, len ) {
		const v1v2Len = v1.distanceTo( v2 );
		return v1.lerp( v2, len / v1v2Len );
	}

 vue The code is as follows :

<template>
	<div>
		<!--  This case demonstrates how to draw Bezier curve at two points -->
		<div id="container"></div>
	</div>

</template>

<script>
	import * as THREE from 'three'
	//  Be careful OrbitControls To add {}, Note that the path is 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();

		},
		// The follow-up will be in beforeDestory Destroy in 
		beforeDestroy() {
			this.scene = null;
			this.renderer = null;
			this.camera = null;
			this.orbitControls = null;
			clearInterval(timerFlyLine);
		},
		methods: {
			//  Scene initialization 
			init() {
				let container = document.getElementById('container');
				this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
				//  Particular attention , The position of the camera should be larger than the size of the geometry 
				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 Does it include alpha ( transparency )  The default is  false
					antialias: true,
					// precision: 'highp',
				})
				// this.renderer.setClearAlpha(0.0); //  Set up alpha, The legal parameter is  0.0  To  1.0  The floating point number between 
				//  Set background color 
				this.renderer.setSize(window.innerWidth, window.innerHeight);
				container.appendChild(this.renderer.domElement);
				//  Add 3D axis 
				//  Red representative x Axis , Green represents y Axis , Blue stands for z Axis 
				// let axesHelper = new THREE.AxesHelper(30);
				// this.scene.add(axesHelper);

				//  Ambient light cannot be used to cast shadows , Because it has no direction .
				var ambienLight = new THREE.AmbientLight(0xcccccc);
				this.scene.add(ambienLight);
				//  Initialize the track controller 
				//  We need to cooperate with animate, Keep looping rendering , Achieve the function of rotating objects with the mouse .
				this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);
				//  Adaptive window size 
				window.addEventListener('resize', this.onWindowResize, false);
				this.addObjects();
			},
			//  Add objects 
			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>

 

原网站

版权声明
本文为[Precipitation of powder]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206110026045631.html