Three.js: Holen Sie sich die Mitte des Objekts

Erstellt am 23. Aug. 2011  ·  11Kommentare  ·  Quelle: mrdoob/three.js

Ich habe ein Problem festgestellt: Wenn Sie auf ein Objekt in der Szene klicken, muss die Kamera auf dieses Objekt zentriert sein. Dafür brauche ich Mittelkoordinaten des Objekts (y-Achse). Wie kann ich das berechnen? Es wurde versucht, alle Scheitelpunkte dieses Objekts zu summieren und nach der Anzahl der Scheitelpunkte zu teilen, aber dies ist natürlich eine falsche Entscheidung.

Question

Hilfreichster Kommentar

Sie können den Begrenzungsrahmen für die Mitte der Geometrie erhalten:

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

Dann können Sie das Ziel Ihrer Kamera auf Objektposition plus Mitte einstellen:

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

Alle 11 Kommentare

object.position.y ?

In unseren Modellen ist es immer 0, Modelle absolut positioniert

Was meinst du absolut positioniert? Alle Objekte befinden sich in 0,0,0, aber der Scheitelpunktcluster befindet sich nicht in der Mitte?

Sie können den Begrenzungsrahmen für die Mitte der Geometrie erhalten:

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

Dann können Sie das Ziel Ihrer Kamera auf Objektposition plus Mitte einstellen:

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

Dies ist eine kleine Funktion, die ich vor einiger Zeit geschrieben habe. Vielleicht hilft es dir ein bisschen.

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

}

Möglicherweise können Sie die Mathematik von alterq einbeziehen (ich wünschte, ich wäre klug genug, um seine Abkürzung zu verstehen).

Ich frage mich ... wäre es nicht einfacher, das zu tun?

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

Ja, wenn Sie nur ein Zentrum benötigen, ist dies einfacher. Wenn Sie bereits einen Begrenzungsrahmen haben oder einen Begrenzungsrahmen für etwas anderes benötigen, ist es einfacher, nur dessen Zentrum zu berechnen.

Hmmm, jetzt frage ich mich, ob diese beiden Methoden die gleichen Ergebnisse liefern würden. Wenn Sie eine Menge Punkte auf einer Seite und eine kleine Anzahl von Punkten auf der anderen Seite haben, ist der Mittelpunkt des Begrenzungsrahmens der Mittelpunkt der Geometrie, während sich der Schwerpunkt im "Schwerpunkt" befindet, näher an einer dichteren Gruppe von Punkten.

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

Ich denke, beide Methoden sind nützlich für verschiedene Anwendungsfälle.

Stimmt das. Der Schwerpunkt des Begrenzungsrahmens ist das, was die meisten Menschen benötigen würden.

ja, ich denke, meine ist doch keine Schwerpunktfunktion: 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 ];

ist jetzt:

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;

(ab r47)

Konzeptionell werden zwei Vektoren hinzugefügt und die Hälfte des Ergebnisses genommen. Ich bin mir nicht sicher, ob es schneller ist, aber es ist mehr ... konkret:

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

        c.divideScalar(2);
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen