A simple arrangement of the three.js (webgl) rotation attribute function of Three, and a simple case of implementing rotation around the axis based on this

A simple arrangement of the three.js (webgl) rotation function of Three, and a simple case of implementing rotation around the axis

content

A simple arrangement of the three.js (webgl) rotation function of Three, and a simple case of implementing rotation around the axis

1. Brief introduction

Second, the simple schematic diagram of the case

3. The realization principle of case rotation

Fourth, matters needing attention

Five, the approximate implementation steps of the case

6. Key code


1. Brief introduction

Some knowledge developed by Three js is convenient to encounter similar problems in the later period, and can be checked and used in time.

This section introduces the arrangement of several commonly used rotation functions in three.js ( webgl ), and on this basis, implements a simple case of rotating a sphere from one point to another. There are many ways to achieve it. This is just for ideas. If there are any deficiencies If there is any problem, please point it out, or if you have a better method, please leave a message.

Several rotation properties/functions in Three js, notably:

  • These rotation functions are based on local rotation
  • Note that the value set here is in radians, which needs to be distinguished from angles
  • Angle to radian MathUtils.degToRad(deg)
  • Radian rotation angle MathUtils.radToDeg (rad)

1. The rotation property in Mesh

property name illustrate property value type Instructions
.rotation The local rotation of the object , in radians radian object3D.rotation.x = MathUtils.degToRad(90)

2. rotateOnAxis rotates an object around the object's axis in local space

Note: axis is preferably a unit vector

method pass parameters Instructions
.rotateOnAxis ( axis : Vector3, angle : Float ) object3D.rotateOnAxis(new Vector3(1,0,0),180)

3. rotateX / rotateY / rotateZ rotate the object around the axis of the local space

method pass parameters parameter type Instructions
.rotateX ( rad : Float ) radian object3D.rotateX (MathUtils.degToRad(90))
.rotateY ( rad : Float ) radian object3D.rotateY(MathUtils.degToRad(90))
.rotateZ ( rad : Float ) radian object3D.rotateZ (MathUtils.degToRad(90))

Second, the simple schematic diagram of the case

3. The realization principle of case rotation

1. The vector angleTo calculates the angle before the A vector and the B vector

2. The vector cross calculates the normal vector of the A vector and the B vector as the rotation axis

3. Using the data obtained above, use Mesh.rotateOnAxis to rotate from point A to point B

Fourth, matters needing attention

1. Mesh.rotateOnAxis is a local rotation. One trick here is to add a parent object at the center of the circle, add the point A object to the parent object, and rotate the parent object, so as to realize the rotational movement from point A to point B

 
 

Five, the approximate implementation steps of the case

The case is based on Threejs    GitHub - mrdoob/three.js: JavaScript 3D Library. 

The engineering framework is created and implemented

1. Create a script, introduce Three, create a basic Three environment, add scenes, cameras, lights, etc.

 

2. Add 3D objects for rotation demonstration

3. Calculate the relevant parameters that need to be rotated, including rotation angle (clockwise/counterclockwise angle), rotation axis vector (clockwise/counterclockwise axis vector), etc.

4. Realize that the ball moves clockwise/counterclockwise from point A to point B, and then call it in the animation or render function

5. Here, you can see the running effect in the browser

6. Key code

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>10TestRotate</title>
</head>
<body>
<script type="importmap">
			{
				"imports": {
					"three": "../../../build/three.module.js"
				}
			}
		</script>

<script type="module">

	import * as THREE from 'three';

	import { OrbitControls } from '../../jsm/controls/OrbitControls.js';
	import Stats from '../../jsm/libs/stats.module.js';

	let scene, camera, renderer, stats;


	var spheremeshT1;
	var spheremeshT2;

	let POSITION_A ;
	let POSITION_B ;
	let POSITION_Center ;
	let T1RotationBasePositionObject;
	let T2RotationBasePositionObject;
	let targetDegreeT1
	let targetDegreeT2
	var degreeT1 = 0
	var degreeT2 = 0
	let T1RotateAixes
	let T2RotateAixes

	init();
	animate();

	function init() {

		// scene
		initScene();

		// camera
		initCamera();


		// light
		initLight();

		// renderer
		initRenderer();

		// OrbitControls
		initOrbitControls();

		stats = new Stats();
		document.body.appendChild( stats.dom );

		// onWindowResize
		window.addEventListener( 'resize', onWindowResize );

		axiesHelper();

		stats = new Stats();
		document.body.appendChild( stats.dom );

		// window.location.href = renderer.domElement.toDataURL( 'image/png' );

		addTestRoateObject();
	}

	function onWindowResize() {

		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();
		renderer.setSize( window.innerWidth, window.innerHeight );

	}

	function initScene( ) {

		scene = new THREE.Scene();

	}

	function initCamera( ) {

		camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 200 );
		camera.position.set( 0, 0, 25 );

	}

	function initLight( ) {

		const ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
		scene.add( ambientLight );

		const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.6 );
		directionalLight.position.set( - 1, 1, 100 );
		scene.add( directionalLight );

	}

	function initRenderer( ) {

		renderer = new THREE.WebGLRenderer( { antialias: true } );
		renderer.setSize( window.innerWidth, window.innerHeight );
		renderer.setPixelRatio( window.devicePixelRatio );
		renderer.setClearColor( 0xcccccc );
		document.body.appendChild( renderer.domElement );

	}

	function initOrbitControls( ) {

		const controls = new OrbitControls( camera, renderer.domElement );
		controls.minDistance = 5;
		controls.maxDistance = 50;
		controls.enablePan = false; // 移动 禁止

	}

	function animate() {

		requestAnimationFrame( animate );
		stats.update();
		render();


	}

	function axiesHelper( ) {

		var helper = new THREE.AxesHelper( 20 );
		scene.add( helper );

	}

	function render() {

		renderer.render( scene, camera );

		rotateRunDataT1T2();
	}


	function addTestRoateObject(){
		POSITION_A = new THREE.Vector3( 0, 5, 0 );
		POSITION_B = new THREE.Vector3( 5, 0, 0 );
		POSITION_Center = new THREE.Vector3( 0, 0, 0 );

		var geometry = new THREE.SphereGeometry( 5, 30 ); //矩形平面
		var material = new THREE.MeshPhongMaterial( {} );
		var spheremesh1 = new THREE.Mesh( geometry, material );
		spheremesh1.position.set(POSITION_Center.x, POSITION_Center.y, POSITION_Center.z);
		scene.add( spheremesh1 );

		var geometryA = new THREE.SphereGeometry( 1, 30 ); //矩形平面
		var materialA = new THREE.MeshPhongMaterial( {
			color: '#cc0000'
		} );
		var spheremeshA = new THREE.Mesh( geometryA, materialA );
		spheremeshA.position.set( POSITION_A.x, POSITION_A.y, POSITION_A.z );
		scene.add( spheremeshA );
		var geometryB = new THREE.SphereGeometry( 1, 30 ); //矩形平面
		var materialB = new THREE.MeshPhongMaterial( {
			color: '#cc00cc'
		} );
		var spheremeshB = new THREE.Mesh( geometryB, materialB );

		spheremeshB.position.set( POSITION_B.x, POSITION_B.y, POSITION_B.z);
		scene.add( spheremeshB );


		var geometryT1 = new THREE.SphereGeometry( 1, 30 ); //矩形平面
		var materialT1 = new THREE.MeshPhongMaterial( {} );
		spheremeshT1 = new THREE.Mesh( geometryT1, materialT1 );
		spheremeshT1.position.set( POSITION_A.x, POSITION_A.y, POSITION_A.z );

		// 辅助旋转
		T1RotationBasePositionObject = new THREE.Mesh( new THREE.SphereGeometry( 0.1, 6 ),materialT1);
		T1RotationBasePositionObject.position.set(POSITION_Center.x, POSITION_Center.y, POSITION_Center.z );
		T1RotationBasePositionObject.add(spheremeshT1);
		scene.add( T1RotationBasePositionObject );

		var geometryT2 = new THREE.SphereGeometry( 1, 30 ); //矩形平面
		var materialT2 = new THREE.MeshPhongMaterial( {} );
		spheremeshT2 = new THREE.Mesh( geometryT2, materialT2 );
		spheremeshT2.position.set( POSITION_A.x, POSITION_A.y, POSITION_A.z );

		// 辅助旋转
		T2RotationBasePositionObject = new THREE.Mesh( new THREE.SphereGeometry( 0.1, 6 ),materialT2);
		T2RotationBasePositionObject.position.set(POSITION_Center.x, POSITION_Center.y, POSITION_Center.z );
		T2RotationBasePositionObject.add( spheremeshT2 );
		scene.add( T2RotationBasePositionObject );

		rotateTestDataT1T2();

	}

	function rotateTestDataT1T2() {

		const v1T1 = new THREE.Vector3( POSITION_A.x, POSITION_A.y, POSITION_A.z );
		console.log( v1T1.x + ' ' + v1T1.y + ' ' + v1T1.z );
		const v2T1 = new THREE.Vector3( POSITION_B.x, POSITION_B.y, POSITION_B.z );
		console.log( v2T1.x + ' ' + v2T1.y + ' ' + v2T1.z );
		targetDegreeT1 = v1T1.angleTo( v2T1 );
		console.log( 'targetDegreeT1 ' + targetDegreeT1 );
		v1T1.cross( v2T1 );
		console.log( v1T1.x + ' ' + v1T1.y + ' ' + v1T1.z );

		//T1RotationBasePositionObject.rotateOnAxis( v1T1.normalize(),targetDegreeT1 )
		T1RotateAixes = v1T1.normalize();

		const v1T2 = new THREE.Vector3( POSITION_A.x, POSITION_A.y, POSITION_A.z );
		console.log( v1T2.x + ' ' + v1T2.y + ' ' + v1T2.z );
		const v2T2 = new THREE.Vector3( POSITION_B.x, POSITION_B.y, POSITION_B.z );
		console.log( v2T2.x + ' ' + v2T2.y + ' ' + v2T2.z );
		targetDegreeT2 = v2T2.angleTo( v1T2 );
		console.log( 'targetDegreeT2 ' + targetDegreeT2 );
		const nl = v2T2.cross( v1T2 );
		console.log( v1T2.x + ' ' + v1T2.y + ' ' + v1T2.z );
		const modifyDegree = Math.PI * 2 - targetDegreeT2;
		console.log( modifyDegree );

		//T2RotationBasePositionObject.rotateOnAxis( v1T2.normalize(), modifyDegree)
		targetDegreeT2 = modifyDegree;
		T2RotateAixes = v2T2.normalize();

	}

	function rotateRunDataT1T2() {
		if ( degreeT1 < targetDegreeT1 ) {
			degreeT1 += 0.01;
			T1RotationBasePositionObject.rotateOnAxis( T1RotateAixes, 0.01 );
		}

		if ( degreeT2 < targetDegreeT2 ) {
			degreeT2 += 0.01;
			T2RotationBasePositionObject.rotateOnAxis( T2RotateAixes, 0.01 );
		}

	}

</script>
</body>
</html>

Guess you like

Origin blog.csdn.net/u014361280/article/details/124346612
Recommended