Three.js: Obtenir le centre de l'objet

Créé le 23 août 2011  ·  11Commentaires  ·  Source: mrdoob/three.js

J'ai rencontré un problème, - en cliquant sur un objet dans la scène, la caméra doit se centrer sur cet objet. Pour cela, j'ai besoin des coordonnées du centre de l'objet (axe y). Comment puis-je calculer cela? J'ai essayé de faire la somme de tous les sommets de cet objet et de le diviser sur le nombre de sommets, mais ceci, bien sûr, une mauvaise décision.

Question

Commentaire le plus utile

Vous pouvez obtenir le centre de la boîte englobante de la géométrie:

geometry.computeBoundingBox();

var centerX = 0.5 * ( geometry.boundingBox.x[ 1 ] - geometry.boundingBox.x[ 0 ] );
var centerY = 0.5 * ( geometry.boundingBox.y[ 1 ] - geometry.boundingBox.y[ 0 ] );
var centerZ = 0.5 * ( geometry.boundingBox.z[ 1 ] - geometry.boundingBox.z[ 0 ] );

Ensuite, vous pouvez définir la cible de votre caméra sur la position de l'objet plus le centre:

camera.target.position.copy( object.position );
camera.target.position.addSelf( new THREE.Vector3( centerX, centerY, centerZ ) );

Tous les 11 commentaires

object.position.y ?

dans nos modèles c'est toujours 0, les modèles sont absolument posés

Que voulez-vous dire en position absolue? Tous les objets sont en 0,0,0 mais le cluster de sommets n'est pas autour du centre?

Vous pouvez obtenir le centre de la boîte englobante de la géométrie:

geometry.computeBoundingBox();

var centerX = 0.5 * ( geometry.boundingBox.x[ 1 ] - geometry.boundingBox.x[ 0 ] );
var centerY = 0.5 * ( geometry.boundingBox.y[ 1 ] - geometry.boundingBox.y[ 0 ] );
var centerZ = 0.5 * ( geometry.boundingBox.z[ 1 ] - geometry.boundingBox.z[ 0 ] );

Ensuite, vous pouvez définir la cible de votre caméra sur la position de l'objet plus le centre:

camera.target.position.copy( object.position );
camera.target.position.addSelf( new THREE.Vector3( centerX, centerY, centerZ ) );

C'est une petite fonction que j'ai écrite il y a quelque temps. Peut-être que ça t'aidera un peu.

getCentroid: function ( mesh ) {

    mesh.geometry.computeBoundingBox();
    boundingBox = mesh.geometry.boundingBox;

    var x0 = boundingBox.x[ 0 ];
    var x1 = boundingBox.x[ 1 ];
    var y0 = boundingBox.y[ 0 ];
    var y1 = boundingBox.y[ 1 ];
    var z0 = boundingBox.z[ 0 ];
    var z1 = boundingBox.z[ 1 ];


    var bWidth = ( x0 > x1 ) ? x0 - x1 : x1 - x0;
    var bHeight = ( y0 > y1 ) ? y0 - y1 : y1 - y0;
    var bDepth = ( z0 > z1 ) ? z0 - z1 : z1 - z0;

    var centroidX = x0 + ( bWidth / 2 ) + mesh.position.x;
    var centroidY = y0 + ( bHeight / 2 )+ mesh.position.y;
    var centroidZ = z0 + ( bDepth / 2 ) + mesh.position.z;

    return mesh.geometry.centroid = { x : centroidX, y : centroidY, z : centroidZ };

}

vous pourriez être en mesure d'incorporer les mathématiques d'alteredq (j'aurais aimé être assez intelligent pour comprendre son raccourci)

Je me demande ... ne serait-il pas plus simple de faire ça?

geometry.centroid = new THREE.Vector3();

for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) {

    geometry.centroid.addSelf( geometry.vertices[ i ].position );

} 

geometry.centroid.divideScalar( geometry.vertices.length );

Ouais, si vous avez juste besoin d'un centre, c'est plus simple. Si vous avez déjà une boîte englobante ou si vous avez besoin d'une boîte englobante pour autre chose, il est plus simple de calculer son centre.

Hmmm, maintenant je me demande si ces deux méthodes donneraient les mêmes résultats. Si vous avez des tonnes de points d'un côté et un petit nombre de points de l'autre côté, le centre de la boîte englobante serait le centre de la géométrie, tandis que le centroïde serait au "centre de gravité", plus proche d'un groupe de points plus dense.

>>> points = [ 0, 10, 11, 12 ]
>>> sum(points)/float(len(points)) # centroid
8.25
>>> 0.5 * (min(points) + max(points)) # center of bounding box
6.0

Je suppose que les deux méthodes sont utiles, pour différents cas d'utilisation.

Vrai que. Le centre de gravité de la boîte englobante est ce dont la plupart des gens auraient besoin.

oui je suppose que la mienne n'est pas vraiment une fonction centroïde après tout: s

var x0 = boundingBox.x[ 0 ];
var x1 = boundingBox.x[ 1 ];
var y0 = boundingBox.y[ 0 ];
var y1 = boundingBox.y[ 1 ];
var z0 = boundingBox.z[ 0 ];
var z1 = boundingBox.z[ 1 ];

est maintenant:

var x0 = boundingBox.min.x;
var x1 = boundingBox.max.x;
var y0 = boundingBox.min.y;
var y1 = boundingBox.max.y;
var z0 = boundingBox.min.z;
var z1 = boundingBox.max.z;

(à partir de R47)

Conceptuellement, il ajoute deux vecteurs et prend la moitié du résultat. Je ne sais pas si c'est plus rapide, mais c'est plus ... concpétuel:

        c.addVectors( 
            object.children[0].geometry.boundingBox.min,
            object.children[0].geometry.boundingBox.max
        );

        c.divideScalar(2);
Cette page vous a été utile?
0 / 5 - 0 notes