Three.js:如何归一化由顶点生成的自定义网格
Hey there! Let’s work through this problem without digging into messy trigonometric calculations or re-learning linear algebra from scratch—Three.js has got your back here.
If you’ve built a cube from 8 custom vertices but can’t get controls to interact with it because the world matrix lacks position/rotation/scale data, here are straightforward solutions:
Option 1: Let Three.js Do the Heavy Lifting (Easiest Approach)
Three.js has built-in utilities to derive these transform values directly from your geometry, no manual matrix math required:
First, calculate the geometry’s bounding box
Custom geometries don’t generate this automatically, so we need to compute it first:const yourCustomGeometry = yourCubeMesh.geometry; yourCustomGeometry.computeBoundingBox();Extract Position
The center of the bounding box is your cube’s world position (assuming your vertices are defined relative to a local origin):const center = new THREE.Vector3(); yourCustomGeometry.boundingBox.getCenter(center); yourCubeMesh.position.copy(center);Extract Scale
The bounding box’s total size gives you the cube’s dimensions—divide by 2 to get the scale values (since the box spans from-mintomax):const size = new THREE.Vector3(); yourCustomGeometry.boundingBox.getSize(size); yourCubeMesh.scale.copy(size).multiplyScalar(0.5);Extract Rotation (No acos Needed!)
Forget manually calculating quaternions or trig functions. Instead, use vertex vectors to build a rotation matrix, then let Three.js convert it to a quaternion:// Grab 3 key vertices (adjust indices based on your vertex order) // Example: v0 = bottom-left, v1 = bottom-right, v2 = top-left of your cube const v0 = yourCustomGeometry.vertices[0]; const v1 = yourCustomGeometry.vertices[1]; const v2 = yourCustomGeometry.vertices[3]; // Calculate X-axis direction (from v0 to v1) const xAxis = v1.clone().sub(v0).normalize(); // Calculate Y-axis direction (from v0 to v2) const yAxis = v2.clone().sub(v0).normalize(); // Derive Z-axis from cross product of X and Y const zAxis = xAxis.clone().cross(yAxis).normalize(); // Build rotation matrix from these axes const rotationMatrix = new THREE.Matrix4(); rotationMatrix.makeBasis(xAxis, yAxis, zAxis); // Convert matrix to quaternion and assign to your mesh yourCubeMesh.quaternion.setFromRotationMatrix(rotationMatrix);
Option 2: Use a Reference Cube for Quick Matching
If you want a shortcut, create a standard Three.js cube that matches your custom cube’s dimensions, then copy its transform values:
import { BufferGeometryUtils } from 'three/addons/utils/BufferGeometryUtils.js'; // Clean up duplicate vertices in your custom geometry const cleanedGeometry = BufferGeometryUtils.mergeVertices(yourCustomGeometry); cleanedGeometry.computeBoundingBox(); // Get center and size as before const center = new THREE.Vector3(); cleanedGeometry.boundingBox.getCenter(center); const size = new THREE.Vector3(); cleanedGeometry.boundingBox.getSize(size); // Create a reference cube const referenceCube = new THREE.Mesh(new THREE.BoxGeometry()); referenceCube.position.copy(center); referenceCube.scale.copy(size).multiplyScalar(0.5); // Copy position/scale to your custom mesh yourCubeMesh.position.copy(referenceCube.position); yourCubeMesh.scale.copy(referenceCube.scale); // Use the rotation method from Option 1 to set quaternion
Final Check
After setting these values, make sure to update the mesh’s world matrix so controls recognize the changes:
yourCubeMesh.updateMatrixWorld(true);
内容的提问来源于stack exchange,提问作者Jim Sosa

