使用 WEBGLRenderer 在没有线框材料和一些线宽的二十面体顶点之间绘制线条 [英] Drawing lines between the Icosahedron vertices without wireframe material and with some line width using WEBGLRenderer

查看:22
本文介绍了使用 WEBGLRenderer 在没有线框材料和一些线宽的二十面体顶点之间绘制线条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Threejs 的新手我需要绘制一个与三角形连接的球体.我使用二十面体以如下方式构造球体

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

但我需要线的宽度更大,但线宽不会显示在窗口中,所以我教了遍历顶点并在顶点之间绘制圆柱/管.(我无法画线,因为 LineBasicMaterial 没有响应 Light.)

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
    
    
}

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

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

**我在使用线框时遇到的问题是它不平滑,而且我无法在 Windows 中增加它的宽度.

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

推荐答案

尽管我确实认为这对于您想要实现的目标来说是一种矫枉过正,但这里的代码可以在两者之间绘制一个胶囊(末端带有球体的圆柱体)两个端点.

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

这篇关于使用 WEBGLRenderer 在没有线框材料和一些线宽的二十面体顶点之间绘制线条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆