使用WEBGLRenderer在没有线框材质和一些线宽的二十面体顶点之间绘制线条

时间:2015-06-04 04:34:50

标签: three.js

我是trijs的新手 我需要绘制一个与三角形相连的球体。我使用二十面体以下列方式构建球体

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

但是我需要线条的宽度更多但是线条宽度不会出现在窗口中所以我教导了循环顶点并在顶点之间绘制圆柱体/管道。 (我无法绘制线条,因为LineBasicMaterial没有响应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
    
    
}

有人可以帮助在两个vector3顶点之间绘制管子/圆柱体吗?

**我面对线框的问题是它不平滑,我不能在窗口增加它的宽度。

2 个答案:

答案 0 :(得分:0)

如果你真的想在两点之间创建一个圆柱,一种方法是在单位空间中创建它,然后将其转换为你的直线。但那是非常肮脏的。

创建它的直观方法是考虑如何在单位空间中完成它?围绕z轴的圆(在x,y中),另一个在z轴下方。

在2d中创建圆很容易:for(angle(0,360,360 / numsteps))(x,y)=(sin(角度),cos(角度))* radius。 (参见例如Calculating the position of points in a circle)。

现在你的气缸的两个对接端不在x,y!但是如果你有两个向量dx,dy你可以将x,y与它们相乘并得到一个3d位置!

那么如何获得dx,dy?一种方法是http://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process 这读起来比实际上更可怕。你从前进方向开始,这是你的路线。 forward = normalize(end-start)。然后你只需选择一个方向&#34; up&#34;。通常(0,1,0)。除非前锋已经接近,否则选择另一个像(1,0,0)。拿他们的十字架产品。这给你&#34;左&#34;。然后在&#34; left&#34;之间取交叉产品。和&#34;前进&#34;得到&#34;对&#34;。现在&#34;离开&#34;和&#34;对&#34;你是dx和dy!

这样你就可以在线的两端做两个圆圈。在它们之间添加三角形,你就有了一个圆柱体!

答案 1 :(得分:0)

尽管我确实认为这对你想要实现的目标来说有点过分,但这里的代码是在两个端点之间绘制一个胶囊(末端有圆柱体的圆柱体)。

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