Three.js: Obtener el centro del objeto

Creado en 23 ago. 2011  ·  11Comentarios  ·  Fuente: mrdoob/three.js

Encontré un problema: al hacer clic en algún objeto en la escena, la cámara debe centrarse en este objeto. Para esto, necesito las coordenadas centrales del objeto (eje y). ¿Cómo puedo calcular esto? Intenté sumar todos los vértices de este objeto y dividirlo por vértices, pero esta, por supuesto, decisión incorrecta.

Question

Comentario más útil

Puede obtener el cuadro delimitador del centro de la geometría:

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 ] );

Luego, puede configurar el objetivo de su cámara en la posición del objeto más el centro:

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

Todos 11 comentarios

object.position.y ?

en nuestros modelos siempre es 0, modelos absolutamente posicionados

¿A qué te refieres con posicionamiento absoluto? ¿Todos los objetos están en 0,0,0 pero el grupo de vértices no está alrededor del centro?

Puede obtener el cuadro delimitador del centro de la geometría:

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 ] );

Luego, puede configurar el objetivo de su cámara en la posición del objeto más el centro:

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

Esta es una pequeña función que escribí hace un tiempo. Quizás te ayude un poco.

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 };

}

es posible que pueda incorporar las matemáticas de Alteredq (desearía ser lo suficientemente inteligente para entender su atajo)

Me pregunto ... ¿no sería más sencillo hacer esto?

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 );

Sí, si solo necesitas un centro, esto es más sencillo. Si ya tiene un cuadro delimitador, o necesita un cuadro delimitador para otra cosa, entonces es más sencillo calcular su centro.

Hmmm, ahora me pregunto si estos dos métodos darían los mismos resultados. Si tiene una gran cantidad de puntos en un lado y una pequeña cantidad de puntos en el otro lado, el centro del cuadro delimitador sería el centro de la geometría, mientras que el centroide estaría en el "centro de gravedad", más cerca de un grupo de puntos más denso.

>>> 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

Supongo que ambos métodos son útiles para diferentes casos de uso.

Eso es cierto. El centroide del cuadro delimitador es lo que la mayoría de la gente necesitaría.

sí, supongo que la mía no es realmente una función centroide después de todo: 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 ];

es ahora:

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;

(a partir de r47)

Conceptualmente, está sumando dos vectores y tomando la mitad del resultado. No estoy seguro si es más rápido, pero es más ... concpetual:

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

        c.divideScalar(2);
¿Fue útil esta página
0 / 5 - 0 calificaciones