Three.js: احصل على مركز الكائن

تم إنشاؤها على ٢٣ أغسطس ٢٠١١  ·  11تعليقات  ·  مصدر: mrdoob/three.js

واجهت مشكلة ، - عند النقر على كائن ما في المشهد ، يجب أن تركز الكاميرا على هذا الكائن. لهذا أحتاج إلى إحداثيات مركزية للكائن (المحور ص). كيف يمكنني حساب هذا؟ حاولت جمع كل رؤوس هذا الكائن وتقسيمه على رؤوس ، لكن هذا بالطبع قرار خاطئ.

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

}

قد تكون قادرًا على دمج رياضيات التغيير (كنت أتمنى لو كنت ذكيًا بما يكفي لفهم الاختصار)

أتساءل ... أليس من الأسهل القيام بذلك؟

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

أعتقد أن كلا الطريقتين مفيدتان لحالات الاستخدام المختلفة.

صحيح أن. Centroid من الصندوق المحيط هو ما يحتاجه معظم الناس.

نعم أعتقد أن وظيفتي ليست حقًا وظيفة النقطه الوسطى بعد كل شيء: 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)

من الناحية المفاهيمية ، إنها تجمع متجهين وتأخذ نصف النتيجة. لست متأكدًا مما إذا كانت أسرع ، لكنها أكثر ... concpetual:

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

        c.divideScalar(2);
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات