Three.js: Obtenha o centro do objeto

Criado em 23 ago. 2011  ·  11Comentários  ·  Fonte: mrdoob/three.js

Eu encontrei o problema, - ao clicar em algum objeto na cena, a câmera deve centralizar neste objeto. Para isso, preciso das coordenadas do centro do objeto (eixo y). Como posso calcular isso? Tentei somar todos os vértices desse objeto e dividi-lo na contagem dos vértices, mas esta, é claro, decisão errada.

Question

Comentários muito úteis

Você pode obter o centro da caixa delimitadora de geometria:

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

Então você pode definir o alvo da sua câmera para a posição do objeto mais o centro:

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

Todos 11 comentários

object.position.y ?

em nossos modelos é sempre 0, modelos absolutamente posicionados

O que você quer dizer com posição absoluta? Todos os objetos estão em 0,0,0, mas o aglomerado de vértices não está ao redor do centro?

Você pode obter o centro da caixa delimitadora de geometria:

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

Então você pode definir o alvo da sua câmera para a posição do objeto mais o centro:

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

Esta é uma pequena função que escrevi há algum tempo. Talvez te ajude um pouco.

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

}

você pode ser capaz de incorporar a matemática do alteredq (gostaria de ser inteligente o suficiente para entender seu atalho)

Eu me pergunto ... não seria mais simples fazer isso?

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

Sim, se você só precisa de um centro, é mais simples. Se você já tem uma caixa delimitadora ou precisa de uma caixa delimitadora para outra coisa, é mais simples calcular seu centro.

Hmmm, agora me pergunto se esses dois métodos dariam os mesmos resultados. Se você tiver toneladas de pontos de um lado e um pequeno número de pontos do outro lado, o centro da caixa delimitadora seria o centro da geometria, enquanto o centróide estaria no "centro de gravidade", próximo a um aglomerado mais denso de pontos.

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

Acho que ambos os métodos são úteis para diferentes casos de uso.

Verdade isso. O centróide da caixa delimitadora é o que a maioria das pessoas precisa.

sim, acho que a minha não é realmente uma função centróide, afinal: 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 ];

é agora:

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)

Conceitualmente, é adicionar dois vetores e tirar a metade do resultado. Não tenho certeza se é mais rápido, mas é mais ... simultâneo:

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

        c.divideScalar(2);
Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

scrubs picture scrubs  ·  3Comentários

makc picture makc  ·  3Comentários

donmccurdy picture donmccurdy  ·  3Comentários

fuzihaofzh picture fuzihaofzh  ·  3Comentários

yqrashawn picture yqrashawn  ·  3Comentários