Three.js: Получить центр объекта

Созданный на 23 авг. 2011  ·  11Комментарии  ·  Источник: mrdoob/three.js

Я столкнулся с проблемой - при нажатии на какой-либо объект в сцене камера должна центрироваться на этом объекте. Для этого мне нужны координаты центра объекта (ось y). Как я могу это вычислить? Пытался просуммировать все вершины этого объекта и разделить на количество вершин, но это, конечно, неправильное решение.

Question

Самый полезный комментарий

Вы можете получить центр ограничивающей рамки геометрии:

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

Затем вы можете установить цель камеры в положение объекта плюс центр:

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

Все 11 Комментарий

object.position.y ?

в наших моделях всегда 0, модели абсолютно позиционированы

Что вы подразумеваете под абсолютным позиционированием? Все объекты находятся в 0,0,0, но кластер вершин находится не вокруг центра?

Вы можете получить центр ограничивающей рамки геометрии:

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

Затем вы можете установить цель камеры в положение объекта плюс центр:

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

Это небольшая функция, которую я написал некоторое время назад. Может, это тебе немного поможет.

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

}

вы могли бы включить математику alteredq (хотелось бы, чтобы я был достаточно умен, чтобы понять его ярлык)

Интересно ... не было бы проще сделать это?

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

Ага, если вам просто нужен центр, это проще. Если у вас уже есть ограничивающая рамка или вам нужна ограничивающая рамка для чего-то еще, то проще просто вычислить ее центр.

Хммм, теперь мне интересно, дадут ли эти два метода одинаковые результаты. Если у вас есть множество точек с одной стороны и небольшое количество точек с другой стороны, центр ограничивающей рамки будет центром геометрии, а центроид будет находиться в «центре тяжести», ближе к более плотному скоплению точек.

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

Думаю, оба метода полезны для разных случаев использования.

Правда что. Центроид ограничивающего прямоугольника - это то, что понадобится большинству людей.

да, я думаю, моя в конце концов не центроидная функция: 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 ];

сейчас:

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;

(по состоянию на r47)

По сути, он складывает два вектора и забирает половину результата. Не уверен, что это быстрее, но более ... непрерывно:

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

        c.divideScalar(2);
Была ли эта страница полезной?
0 / 5 - 0 рейтинги