2013-02-28 3 views
3

(новый StackOverflow, новый для WebGL/three.js, ...)
Three.js - два очка, один цилиндр, выравнивают выпуск

Я использую three.js R54 для построения форс- направленный граф. ребра между узлами - это ТРИ. Линии, которые хороши, но строки не могут быть выбраны с помощью raycaster. поэтому моя цель - взять цилиндры вместо (или вместе с) линий (также потому, что я могу сделать еще кое-что: используя текстуры, ...)

Это то, что я делаю, чтобы поместить цилиндры:

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

(descripted в: http://www.fastgraph.com/makegames/3drotation/)

Таким образом, цилиндры расположены справа смещения и согласования в какой-то образом, но не к двум точкам (начало, конец) краев.
любое предложение будет оценено!

ответ

4

с помощью этого: 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); 
    } 
+1

ДА !!! оно работает! хорошо я видел ваш упомянутый пример, но я не дал ему попробовать, потому что я действительно не понимаю, что там происходит. Я более подробно рассмотрю используемые функции в рамках. Спасибо большое! – ewo

+0

вы должны уметь видеть http://meta.stackexchange.com/questions/167748/user-cannot-accept-my-answer – jdregister

+2

В r58 rotateX устарел для makeRotationX и multiplySelf, addSelf, subSelf необходимо изменить на multiply, add, sub соответственно – jdregister

0

@ ответ jdregister не работали не совсем для меня в R77, так как цилиндр оказался остроумием h его центр в vstart (вращение и взгляд в противном случае были прекрасными).

Эта модификация ко второй последней строке R58 + ответ сделал трюк:

mesh.position.set(position.x, position.y, position.z); 
+0

Вы можете сделать это: 'mesh.position.copy (position);' – WestLangley

Смежные вопросы