Domanda

Sono nuovo al mondo Three.js ... La mia domanda è: posso legano due forme diverse insieme come una sola forma? Per esempio vincolante sfera e del cilindro insieme come una sola?

È stato utile?

Soluzione

Tipo di, sì, ci sono diverse opzioni:

  1. via gerarchia Si può semplicemente aggiungere una maglia a un altro utilizzando la funzione add()
  2. con funzione di merge() GeometryUtil ai vertici di unione e maglie di due geometria oggetti in uno
  3. utilizzando un editor 3D di base che supporta le operazioni booleane tra mesh e l'esportazione.

Il metodo 1 è piuttosto semplice:

var sphere = new THREE.Mesh( new THREE.SphereGeometry(100,16,12),new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ));
                var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(100, 100, 200, 16, 4, false ),new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ));
                cylinder.position.y = -100;
                scene.add(sphere);
                scene.add(cylinder);

Si noti che il 16 si ripete, in modo che il livello di suddivisioni in una maglia corrisponde l'altra (per un look decente)

Metodo 2.1 - via GeometryUtils

//make a sphere
                var sg = new THREE.SphereGeometry(100,16,12);
                //make cylinder - ideally the segmentation would be similar to predictable results
                var cg = new THREE.CylinderGeometry(100, 100, 200, 16, 4, false );
                //move vertices down for cylinder, so it maches half the sphere - offset pivot
                for(var i = 0 ; i < cg.vertices.length; i++) cg.vertices[i].position.y -= 100;
                //merge meshes
                THREE.GeometryUtils.merge(sg,cg);
                var mesh = new THREE.Mesh( sg,new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ));
                scene.add(mesh);

Metodo 2.2 unione di un tornio semisfera e un cilindro:

var pts = [];//points array
                var detail = .1;//half-circle detail - how many angle increments will be used to generate points
                var radius = 100;//radius for half_sphere
                var total = Math.PI * .51;
                for(var angle = 0.0; angle < total ; angle+= detail)//loop from 0.0 radians to PI (0 - 180 degrees)
                    pts.push(new THREE.Vector3(0,Math.cos(angle) * radius,Math.sin(angle) * radius));//angle/radius to x,z
                var lathe = new THREE.LatheGeometry( pts, 16 );//create the lathe with 12 radial repetitions of the profile
                //rotate vertices in lathe geometry by 90 degrees
                var rx90 = new THREE.Matrix4();
                rx90.setRotationFromEuler(new THREE.Vector3(-Math.PI * .5,0,0));
                lathe.applyMatrix(rx90);
                //make cylinder - ideally the segmentation would be similar for predictable results
                var cg = new THREE.CylinderGeometry(100, 100, 200, 16, 4, false );
                //move vertices down for cylinder, so it maches half the sphere
                for(var i = 0 ; i < cg.vertices.length; i++) cg.vertices[i].position.y -= 100;
                //merge meshes
                THREE.GeometryUtils.merge(lathe,cg);
                var mesh = new THREE.Mesh( lathe, new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ) );
                mesh.position.y = 150;
                scene.add(mesh);

L'un problema che non può risolvere momentaneamente proviene dalle facce che si trovano all'interno della rete. Idealmente quelli sarebbero normali capovolte in modo da non rendere, ma non hanno trovato una soluzione rapida per questo.

Il 3 ° è abbastanza semplice. La maggior parte dei pacchetti 3D consentono un'operazione booleana sui mesh (ad esempio fusione due maglie insieme con l'operazione di somma (+ Mesha meshB)). Prova a creare un cilindro e una sfera in Blender (gratuito, opensource), che già ha un Three.js esportatore. In alternativa è possibile esportare un file obj del reticelle compreso il vostro editor 3D o scelta fuse e utilizzare il convert_obj_three script.

Aggiorna

ho trovato ancora un altro metodo, che potrebbe essere più facile / più intuitivo. Ricordate le operazioni booleane che ho citato sopra?

Si scopre che c'è una libreria impressionante js solo per questo: Geometria Solida Costruttiva :

CSG biblioteca anteprima dalla pagina GitHub del proprietario

Chandler Prall ha scritto alcune funzioni a portata di mano per la connessione CSG con Three.js . Quindi, con la libreria CSG e il Three.js wrapper per esso , si può semplicemente fare questo:

var cylinder = THREE.CSG.toCSG(new THREE.CylinderGeometry(100, 100, 200, 16, 4, false ),new THREE.Vector3(0,-100,0));
var sphere   = THREE.CSG.toCSG(new THREE.SphereGeometry(100,16,12));
var geometry = cylinder.union(sphere);
var mesh     = new THREE.Mesh(THREE.CSG.fromCSG( geometry ),new THREE.MeshNormalMaterial());

che vi dà un risultato bello (nessun problema con le facce supplementare / normali flipping / etc.):

cilindro sfera unione con CSG e Three.js

Altri suggerimenti

I involucro aggiornato per Three.js R62, si può trovare qui: https://github.com/kraag22/csg- involucro

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top