如何在three.js中制作道路标记的平行曲线?

时间:2017-08-22 11:11:43

标签: javascript three.js bezier curve

我试图绘制一些平行曲线,一条在另一条旁边,但是如果我通过在一个轴上修改/平移它们的位置来分隔它们,结果就不是我要找的了

代码很简单,制作中心路径更加便捷,而且两边都有其他材料克隆。

var bezier = new THREE.CubicBezierCurve3(
                new THREE.Vector3(initx, inity, 0),
                new THREE.Vector3(cp1x, cp1y, 0),
                new THREE.Vector3( cp2x, cp2y, 0),
                new THREE.Vector3(finalx, finaly, 0)
                );

var curvePath = new THREE.CurvePath();
curvePath.add(bezier);

var path = curvePath.createPointsGeometry( 5 );
path.computeLineDistances();

var lineMat = new THREE.LineDashedMaterial({ color: 0xFFFFFF,
                                             dashSize: 3,
                                             gapSize: 2, 
                                             linewidth: 10});

var curveLine = new THREE.Line(path, lineMat);

curveLine.rotation.set(-Math.PI/2,0,0);
curveLine.position.y = 0.1;

var leftLine = curveLine.clone();
leftLine.material = matLine;

var rightLine = curveLine.clone();
rightLine.material = matLine;

leftLine.translateX(-3.5);
rightLine.position.set(3.5,0,0);

scene.add(curveLine);
scene.add(leftLine);
curveLine.add(rightLine);

这是结果: enter image description here

这是我正在寻找的一些例子:

d source: https://pomax.github.io/bezierjs/ source: https://pomax.github.io/bezierjs/

最后两张图片来自Bezier.js库。

我认为将偏移应用于曲线,使用第一行的绘制另一行可能是解决方案,但我在文档中找不到任何有用的东西。 我认为也可以从切线轴的距离或类似的东西画一条线,但它可能是一种更简单的方法,任何想法?

我查看了this,但它是直线。

1 个答案:

答案 0 :(得分:2)

最后,我自己做了。

我使用 getTangent()并将其旋转90度来计算主曲线的切线法线以获得正常。我为该法线创建了更多顶点,将其值乘以标量。然后我从世界坐标中的法线得到我想要的点并连接它们创建一个CatmullRomCurve3几何:

for(var i = 0.0; i <= 1.0; i += 0.2){

    var point = curvePath.getPointAt(i);

    var tangent = curvePath.getTangent(i);
    var extension1 = new THREE.Vector3(tangent.x*2, tangent.y*2, 0);
    var extension2 = new THREE.Vector3(extension1.x*2, extension1.y*2, 0);

    var tangentGeometry = new THREE.Geometry();
    tangentGeometry.vertices.push(tangent, extension1, extension2);

    var tangentLine = new THREE.Line(tangentGeometry,greenMaterial);
    tangentLine.position.set(point.x, point.y, point.z);

    normal.updateMatrixWorld(); // VERY IMPORTANT

    var normal = tangentLine.clone();
    normal.rotateZ(Math.PI/2);

    var normalLastVertex = normal.geometry.vertices[2].clone();
    normalLastVertex.applyMatrix4(normal.matrixWorld); //convert to world coords.

    pointsArray.push(normalLastVertex); //for using them out of the loop

    curveLine.add(tangentLine);
    curveLine.add(normal);
}

这里我在点数组中有最后一个法线顶点,所以我必须创建连接它们的样条曲线。

    var splineCurveOffsetLeft = new THREE.CatmullRomCurve3([

       new THREE.Vector3((pointsArray[0].x), pointsArray[0].y, 0),
       new THREE.Vector3((pointsArray[1].x), pointsArray[1].y, 0),
       new THREE.Vector3((pointsArray[2].x), pointsArray[2].y, 0),
       new THREE.Vector3((pointsArray[3].x), pointsArray[3].y, 0),
       new THREE.Vector3((pointsArray[4].x), pointsArray[4].y, 0),
       new THREE.Vector3((pointsArray[5].x), pointsArray[5].y, 0)           
    ]);
splineCurveOffsetLeft.type = 'catmullrom';
splineCurveOffsetLeft.closed = false;

var offsetGeometry = new THREE.Geometry();
offsetGeometry.vertices = splineCurveOffsetLeft.getPoints(6);

var offsetLine = new THREE.Line(offsetGeometry, cyanMaterial);

offsetLine.rotation.set(-Math.PI/2, 0, 0);
offsetLine.position.y=0.1;

scene.add(offsetLine);

我为其他偏移线做了同样的事情,只是反转它的旋转,这就是结果:

Offset curve

绿色=切线,红色=法线,青色=平行曲线