5

(stackoverflow の新機能、webgl/three.js の新機能、...)

three.js r54 を使用して、力指向グラフをプロットしています。ノード間のエッジは THREE.Lines ですが、これは問題ありませんが、線はレイキャスターでは選択できません。だから私の目的は、線の代わりに(/と一緒に)円柱を取ることです(また、テクスチャを使用して、さらにいくつかのことができるからです...)

これは、シリンダーを配置するために私がやっていることです:

// init reference vector
var upVec = new THREE.Vector3(0,1,0);

//---withhin a loop---
// get direction
var direction = startPoint.subSelf(endPoint).clone();

// half length for cylinder height
var halfLength = direction.length() * 0.5;  

// get offset
var offset = endPoint.clone().addSelf(direction.clone().multiplyScalar(0.5));

// normalize direc
direction.normalize();

//newUpVec = upVec - (upVec *(dot) direction) * direction - projection of direction
var newUpVec = upVec.clone().subSelf(direction.clone().multiplyScalar(upVec.dot(direction.clone()))).normalize();
var right = newUpVec.clone().crossSelf(direction.clone());

//build rotation matrix
var rot = new THREE.Matrix4(right.x, right.y, right.z, 0,
                            newUpVec.x, newUpVec.y, newUpVec.z, 0, 
                            direction.x, direction.y, direction.z,0,
                            0,0,0,1);
//build translation matrix
var transla = new THREE.Matrix4(1, 0, 0, offset.x,
                                0, 1, 0, offset.y,
                                0, 0, 1, offset.z,
                                0, 0, 0, 1);

 //build transformation matrix
 var transfo = new THREE.Matrix4().multiply(transla, rot);

 // create geometry
 var cylgeo = new THREE.CylinderGeometry(2, 2, halfLength * 2, 12, 1, false);
 cylgeo.applyMatrix(transfo);

 var cylMesh = new THREE.Mesh(cylgeo, new THREE.MeshLambertMaterial({color:0x000000, 
            wireframe: true, shading: THREE.FlatShading}));

(説明: http://www.fastgraph.com/makegames/3drotation/ )

したがって、円柱は正しいオフセットに配置され、何らかの方法で整列しますが、エッジの 2 つのポイント (開始、終了) には配置されません。
任意の提案をいただければ幸いです!

4

4 に答える 4

8

それを使用して: object3d-rotation-to-align-to-a-vector

2 つの Vector3 とシーンが与えられた場合:

function drawCylinder(vstart, vend,scene){
var HALF_PI = +Math.PI * .5;
var distance = vstart.distanceTo(vend);
var position  = vend.clone().addSelf(vstart).divideScalar(2);

var material = new THREE.MeshLambertMaterial({color:0x0000ff});
var cylinder = new THREE.CylinderGeometry(10,10,distance,10,10,false);

var orientation = new THREE.Matrix4();//a new orientation matrix to offset pivot
var offsetRotation = new THREE.Matrix4();//a matrix to fix pivot rotation
var offsetPosition = new THREE.Matrix4();//a matrix to fix pivot position
orientation.lookAt(vstart,vend,new THREE.Vector3(0,1,0));//look at destination
offsetRotation.rotateX(HALF_PI);//rotate 90 degs on X
orientation.multiplySelf(offsetRotation);//combine orientation with rotation transformations
cylinder.applyMatrix(orientation)

var mesh = new THREE.Mesh(cylinder,material);
mesh.position=position;
scene.add(mesh);

}

r58+ コード:

 function drawCylinder(vstart, vend,scene){
    var HALF_PI = Math.PI * .5;
    var distance = vstart.distanceTo(vend);
    var position  = vend.clone().add(vstart).divideScalar(2);

    var material = new THREE.MeshLambertMaterial({color:0x0000ff});
    var cylinder = new THREE.CylinderGeometry(10,10,distance,10,10,false);

    var orientation = new THREE.Matrix4();//a new orientation matrix to offset pivot
    var offsetRotation = new THREE.Matrix4();//a matrix to fix pivot rotation
    var offsetPosition = new THREE.Matrix4();//a matrix to fix pivot position
    orientation.lookAt(vstart,vend,new THREE.Vector3(0,1,0));//look at destination
    offsetRotation.makeRotationX(HALF_PI);//rotate 90 degs on X
    orientation.multiply(offsetRotation);//combine orientation with rotation transformations
    cylinder.applyMatrix(orientation)

    var mesh = new THREE.Mesh(cylinder,material);
    mesh.position=position;
    scene.add(mesh);
    }
于 2013-03-01T15:09:17.120 に答える
1

@jdregisterの答えは、R77ではうまく機能しませんでした。これは、円柱がvstartの中心になったためです(回転とlookAtはそれ以外の場合は問題ありませんでした)。

R58 +の回答の最後から2番目の行へのこの変更は、トリックを行いました:

mesh.position.set(position.x, position.y, position.z);
于 2016-06-04T06:34:19.857 に答える