# How do I align a cylinder along an axis?

I am trying to position and orient a set of cylinders. As input I have a list of xyz locations. Each cylinder is positioned and oriented from successive pairs of xyz values. One after another. Here is the code:

``````const geometries = []
let previousVertex = undefined

const vertices = EnsembleManager.getSingleCentroidVerticesWithTrace(trace)

for (let vertex of vertices) {

if (previousVertex) {

// create cylinder with length equal to the distance between successive vertices
const distance = previousVertex.distanceTo( vertex )

// move cylinder to location central between vertices
const { x:cx, y:cy, z:cz } = previousVertex.lerp(vertex, 0.5)
cylinder.translate(cx, cy, cz)

// use quaterion to orient cylinder to align along the vector formed between
// the pair of vertices
const { x:px, y:py, z:pz } = previousVertex
const { x, y, z } = vertex

const alignmentVector = new THREE.Vector3(x-px, y-py, z-pz)

const cylinderDefaultAxis = new THREE.Vector3(0, 1, 0)

const quaternion = new THREE.Quaternion()
quaternion.setFromUnitVectors(cylinderDefaultAxis, alignmentVector.normalize())
cylinder.applyQuaternion(quaternion)

geometries.push(cylinder)
}

previousVertex = vertex
}

const material = sceneManager.stickMaterial.clone();
const mesh = new THREE.Mesh(mergeBufferGeometries( geometries ), material);

``````

When I run this code none of the cylinders appear. If I remove the quaterion code, the cylinders appear in the correct location but lack - obviously - the required orientation.

What am I missing here?

1 Like

Hi!
I would log variables and check if there are ones that have NaN or undefined values.

Solved. Here is the code for anyone with a similar need:

``````createSticks(trace, stickRadius) {

const geometries = []
const vertices = EnsembleManager.getSingleCentroidVerticesWithTrace(trace)

const endPoints = []
for (let i = 0; i < vertices.length - 1; i++) {
endPoints.push({ a: vertices[ i ], b: vertices[ i + 1 ] })
}

for (let { a, b } of endPoints) {

// stick has length equal to distance between endpoints
const distance = a.distanceTo( b )

// stick endpoints define the axis of stick alignment
const { x:ax, y:ay, z:az } = a
const { x:bx, y:by, z:bz } = b
const stickAxis = new THREE.Vector3(bx-ax, by-ay, bz-az).normalize()

// Use quaternion to rotate cylinder from default to target orientation
const quaternion = new THREE.Quaternion()
const cylinderUpAxis = new THREE.Vector3( 0, 1, 0 )
quaternion.setFromUnitVectors(cylinderUpAxis, stickAxis)
cylinder.applyQuaternion(quaternion)

// Translate oriented stick to location between endpoints
cylinder.translate((bx+ax)/2, (by+ay)/2, (bz+az)/2)