# How to orientate the top face of a cylinder to another point

I’ve to build a tubular structure out of branches. Each branch has a starting position, an end position, a starting direction and an end direction. With this 4 elements I want to draw cylinders connected to each other. Unfortunately, I can not use ofNode like I did here How to draw a cylinder starting from 2 ofNode because it turned out to be too slow.

My current problem is to draw a single cylinder, what I would like to have is this:

Where A is `startingPos` and B is `endingPos`. B-A is the `startingDir` and C - B is the the `endDir`. C is the `lookingAt` point that the top face should look.

What I’m obtaining now, is this:

As you see, the rotation of the top face happens on an axis that is not what it should be.

To rotate the top face, I use:
the formula:
angle = acos(v1 dot v2)
axis = norm(v1 cross v2)

Therefore:

``````auto angle = acos(glm::dot(glm::normalize(startDir), glm::normalize(endDir)));
auto axis = glm::normalize(glm::cross(startDir, endDir));
glm::mat4x4 rotMat = glm::axisAngleMatrix(axis, angle);
``````

This is the whole code that I’m using to draw this scene:

``````#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
//light.enable();
glm::vec3 startPos = glm::vec3(0.0f,0.0f, 0.0f);
glm::vec3 endPos = glm::vec3(0.0f, 40.0f, 0.0f);
lookingAt = glm::vec3(40.0f, 75.0f, 0.0f);
glm::vec3 startDir = glm::normalize(endPos - startPos);
glm::vec3 endDir = glm::normalize(lookingAt - endPos);

createTube(startPos, endPos, startDir, endDir, this->mesh);
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
ofEnableDepthTest();
cam.begin();
ofSetColor(0,0,0,100);
mesh.drawWireframe();
auto n = mesh.getNormals();
auto v = mesh.getVertices();
float normalLength = 20.;

ofSetColor(255,0,0,70);
for(unsigned int i=0; i < n.size() ;i++){
ofDrawLine(.98*v[i].x,.98*v[i].y,.98*v[i].z,
.98*v[i].x+n[i].x*normalLength*.2,.98*v[i].y+n[i].y*normalLength*.2,.98*v[i].z+n[i].z*normalLength*.2);

}

ofDrawSphere(lookingAt.x, lookingAt.y, lookingAt.z, 3);

cam.end();
ofDisableDepthTest();
}

void ofApp::createTube(glm::vec3 startPos, glm::vec3 endPos, glm::vec3 startDir, glm::vec3 endDir, ofMesh& mesh){
bool cap = false;
int resolution = 6;
int textureRepeat = 1;
float length = glm::distance(startPos, endPos);
const int scaledRadius = 8;//for now, do not scale the branches;

auto angle = acos(glm::dot(glm::normalize(startDir), glm::normalize(endDir)));
auto axis = glm::normalize(glm::cross(startDir, endDir));
glm::mat4x4 rotMat = glm::axisAngleMatrix(axis, angle);

// Cylinder body
int first = mesh.getNumVertices();
for (int i = 0; i <= resolution; i++) {
// if it is the last face, close it where the first face
// was started
if (i == resolution) {

} else {

}
}

for (int i = 0; i <= resolution; i++) {
//calculate x and y component
float theta = 2.0f * 3.1415926f * float(i) / float(resolution);
float x = radius * cosf(theta);
float z = radius * sinf(theta);

glm::vec3 offset = glm::vec3(x, startPos.y, z);
glm::vec3 circleBottom = startPos + offset;
glm::vec3 direction = glm::normalize(circleBottom);

glm::vec3 circleTop =  glm::vec3(rotMat * glm::vec4((endPos + offset),0.0));
glm::vec3 directionTop = endDir;

// bottom
//botton and top vertices share the same normal
glm::vec3 normal = glm::normalize(circleBottom-startPos);

//top
}
}
``````

Does anyone have some suggestion?

It was a stupid error in matrix order multiplication:

I leave the code here, maybe it will be useful for someone. The math about the angle between 2 vectors it is well explained here http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm

``````    for (int i = 0; i <= resolution; i++) {
//the circle, this is the element that will be moved
float theta = 2.0f * 3.1415926f * float(i) / float(resolution);
float x = radius * cosf(theta);
float z = radius * sinf(theta);
glm::vec4 circle = glm::vec4(x, 0.0f, z, 1.0f); // it is a vec4 because
// it will be used with the matrices, and w is 1.0 because it is a postion

//let's keep for later the adjustement on the circle bottom,
// rotation and translation has to be applied here too, but for now
// I keep it to 0,0,0
glm::vec3 circleBottom = glm::vec3(circle);

// first rotate the plane on the axis, than move it up
glm::mat4 tranMat = glm::translate(endPos);
glm::vec4 circleTop =  glm::vec4(rotMat * circle);
glm::vec4 circleTopRotated = tranMat * circleTop;

glm::vec2 tcoord;
tcoord.x = ofMap(i, 0.f, resolution, 0.f, xWrapLimit);

// bottom
//botton and top vertices share the same normal
glm::vec3 normal = glm::normalize(circleBottom-startPos);
tcoord.y = 0;