Three.js - two points, one cylinder, alignment

(new for stackoverflow, new for webgl / three.js, ...)

I am using three.js r54 to plot a force oriented graph. edges between nodes are THREE. Lines that are good, but lines cannot be selected with raycaster. so my goal is to take cylinders instead of (/ along with) lines (also because I can do something else: using textures, ...)

this is what i do to put the cylinders:

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

(described at: http://www.fastgraph.com/makegames/3drotation/ )

Thus, the cylinders are located at the right offset and are aligned in some way, but not to two points (beginning, end) of the edges.
Any suggestion will be appreciated!

+3
source share
3 answers

using this: object3d-rotation-to-align-to-a-vector

given 2 Vector3 and scene:

 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 + code:

  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); } 
+5
source

@jdregister's answer didn’t quite work for me in R77, as the cylinder turned out to be centered in vstart (rotation and lookAt were otherwise).

This modification to the second last line of the R58 + answer did the trick:

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

In R87, "vend.clone (). Add (vstart) .divideScalar (2);" does not work

You can position an element as follows: mesh.position.copy(start); mesh.position.lerp(end, 0.5); mesh.position.copy(start); mesh.position.lerp(end, 0.5);

Everyone else from R58 is fine :)

0
source

All Articles