When drawing in OpenGL and related APIs you usually have one or more models. In your case, this would be the cylinder and the icosahedron. The models are generally generated at some default size which may or may not suit your needs for a particular task. You move them, scale them, and rotate them by setting up a model matrix which describes how you want to transform them.
So how would this work in your case? I recommend having 2 functions. One which draws a unit cylinder and another which draws a unit icosahedron. Say you have a data structure for your coordinates like this (I'm assuming a C-like language):
typedef struct Position3D {
float x;
float y;
float z;
} Position3D;
You can then construct a triangle by making a structure for one:
typedef struct Triangle3D {
Position3D p0;
Position3D p1;
Position3D p2;
} Triangle3D;
Then you'd have functions for generating the vertices you need. Something like this:
void generateCylinder (Triangle3D* triangles) // <-assumes you allocated triangles before calling and that you have enough space for all of them!
{
int i = 0;
const float kRadius = 1.0;
const float kDeltaH = 0.1; // <- change this to make the mesh more or less dense
const float kDeltaAngle = M_PI / 10.0; // <- change this to make the mesh more or less curved
for (float h = -1.0; h < 1.0; h += kDeltah)
{
for (float angle = 0; angle < 2.0 * M_PI; angle += kDeltaAngle)
{
float x = kRadius * cos(angle);
float y = h;
float z = kRadius * sin(angle);
//... add points to triangles array here...
// p0 = <x,y,z>
// p1 = <x, y + kDeltaH, z>
// p1 = <x + radius * cos(angle + kDeltaAngle), y, z + radius * sin(angle + kDeltaAngle)>
}
}
}
And a similar function for the icosahedron.
Next, you'll create a matrix for every object you draw and send that to your shader before drawing it. So you'll have the translations for the vertices of the (big) icosahedron, and you want to draw a (small) icosahedron at each one. You'd do the following:
float translationMatrix [ 16 ] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
translationMatrix [ 12 ] = xPos;
translationMatrix [ 13 ] = yPos;
translationMatrix [ 14 ] = zPos;
GLuint modelMatrixLoc = glGetUniformLocation(program, "modelMatrix");
glUniformMatrix4fv(modelMatrixLoc, 1, GL_FALSE, translationMatrix);
Then you'd draw your icosahedron. For the cylinders you would need to scale vertically, rotate to the appropriate angle and translate it to the position between 2 icosahedrons.