0

I'm new to threejs I need to draw a sphere connected with triangles. I use Icosahedron to construct the sphere in the following way

var material = new THREE.MeshPhongMaterial({
    emissive   : 0xffffff,
    transparent: true,
    opacity    : 0.5,
    wireframe : true
});
var icogeo = new THREE.IcosahedronGeometry(80,2);
var mesh = new THREE.Mesh(icogeo, material);
scean.add(mesh);

But i need the width of the line to be more but line width won't show up in windows so i taught of looping through the vertices and draw a cylinder/tube between the vertices. (I can't draw lines because the LineBasicMaterial was not responding to Light.)

for(i=0;i<icogeo.faces.length;i++){
    var face = icogeo.faces[i];
    //get vertices from face and draw cylinder/tube between the three vertices
    
    
}

Can some one please help on drawing the tube/cylinder between two vector3 vertices?

**the problem i'm facing with wireframe was it was not smooth and i can't increase width of it in windows.

WestLangley
  • 102,557
  • 10
  • 276
  • 276
Phani
  • 1
  • 1

2 Answers2

0

If you really want to create a cylinder between two points one way to do is to create it in a unit space and then transform it to your line. But that is very mathy.

An intuitive way to create it is to think about how would you do it in a unit space? A circle around the z axis (in x,y) and another one a bit down z.

Creating a circle in 2d is easy: for ( angle(0,360,360/numsteps) ) (x,y)=(sin(angle),cos(angle))*radius. (see for example Calculating the position of points in a circle).

Now the two butt ends of your cylinder are not in x,y! But If you have two vectors dx,dy you can just multiply your x,y with them and get a 3d position!

So how to get dx, dy? One way is http://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process which reads way more scary than it is. You start with your forward direction, which is your line. forward = normalize(end-start). Then you just pick a direction "up". Usually (0,1,0). Unless forward is already close to up, then pick another one like (1,0,0). Take their cross product. This gives you "left". Then take the cross product between "left" and "forward" to get "right". Now "left" and "right" are you dx and dy!

That way you can make two circles at the two ends of your line. Add triangles in between and you have a cylinder!

Community
  • 1
  • 1
starmole
  • 4,974
  • 1
  • 28
  • 48
0

Even though I do believe it is an overkill for what you are trying to achieve, here is code that draws a capsule (cylinder with spheres at the end) between two endpoints.

/**
 * Returns a THREE.Object3D cylinder and spheres going from top to bottom positions
 * @param radius - the radius of the capsule's cylinder
 * @param top, bottom - THREE.Vector3, top and bottom positions of cone
 * @param radiusSegments - tessellation around equator
 * @param openTop, openBottom - whether the end is given a sphere; true means they are not
 * @param material - THREE.Material
 */
function createCapsule (radius, top, bottom, radiusSegments, openTop, openBottom, material)
{
    radiusSegments = (radiusSegments === undefined) ? 32 : radiusSegments;
    openTop = (openTop === undefined) ? false : openTop;
    openBottom = (openBottom === undefined) ? false : openBottom;

    var capsule = new THREE.Object3D();

    var cylinderAxis = new THREE.Vector3();
    cylinderAxis.subVectors (top, bottom);  // get cylinder height

    var cylinderGeom = new THREE.CylinderGeometry (radius, radius, cylinderAxis.length(), radiusSegments, 1, true); // open-ended
    var cylinderMesh = new THREE.Mesh (cylinderGeom, material);

    // get cylinder center for translation
    var center = new THREE.Vector3();
    center.addVectors (top, bottom);
    center.divideScalar (2.0);

    // pass in the cylinder itself, its desired axis, and the place to move the center.
    makeLengthAngleAxisTransform (cylinderMesh, cylinderAxis, center);
    capsule.add (cylinderMesh);

    if  (! openTop || ! openBottom)
    {
        // instance geometry
        var hemisphGeom = new THREE.SphereGeometry (radius, radiusSegments, radiusSegments/2, 0, 2*Math.PI, 0, Math.PI/2);

        // make a cap instance of hemisphGeom around 'center', looking into some 'direction'
        var makeHemiCapMesh = function (direction, center)
        {
            var cap = new THREE.Mesh (hemisphGeom, material);

            makeLengthAngleAxisTransform (cap, direction, center);

            return cap;
        };

        // ================================================================================

        if  (! openTop)
            capsule.add (makeHemiCapMesh (cylinderAxis, top));

        // reverse the axis so that the hemiCaps would look the other way
        cylinderAxis.negate();

        if  (! openBottom)
            capsule.add (makeHemiCapMesh (cylinderAxis, bottom));
    }

    return capsule;
}

// Transform object to align with given axis and then move to center 
function makeLengthAngleAxisTransform (obj, align_axis, center)
{
    obj.matrixAutoUpdate = false;

    // From left to right using frames: translate, then rotate; TR.
    // So translate is first.
    obj.matrix.makeTranslation (center.x, center.y, center.z);

    // take cross product of axis and up vector to get axis of rotation
    var yAxis = new THREE.Vector3 (0, 1, 0);

    // Needed later for dot product, just do it now;
    var axis = new THREE.Vector3();
    axis.copy (align_axis);
    axis.normalize();

    var rotationAxis = new THREE.Vector3();
    rotationAxis.crossVectors (axis, yAxis);
    if  (rotationAxis.length() < 0.000001)
    {
        // Special case: if rotationAxis is just about zero, set to X axis,
        // so that the angle can be given as 0 or PI. This works ONLY
        // because we know one of the two axes is +Y.
        rotationAxis.set (1, 0, 0);
    }
    rotationAxis.normalize();

    // take dot product of axis and up vector to get cosine of angle of rotation
    var theta = -Math.acos (axis.dot (yAxis));
//  obj.matrix.makeRotationAxis (rotationAxis, theta);
    var rotMatrix = new THREE.Matrix4();
    rotMatrix.makeRotationAxis (rotationAxis, theta);
    obj.matrix.multiply (rotMatrix);
}
gaitat
  • 12,449
  • 4
  • 52
  • 76