如何在 three.js 中制作平行曲线用于道路标记?
How to make parallel curves in three.js for road marking?
我正在尝试绘制一些 平行 曲线,一条接一条,但如果我将它们分开 modifying/translating 它们在一个轴上的位置,结果不是我要找的。
代码很简单,一个贝塞尔曲线来制作中央路径并用其他 material 克隆两侧。
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);
这是结果:
这是我正在寻找的一些示例:
最后两张图片来自 Bezier.js 库。
我认为对曲线应用偏移,或绘制另一条线使用法线[=第一个的 36=] 可能是解决方案,但我在文档中找不到任何有用的东西。
我认为也可以从切线轴或类似的距离画一条线,但这可能是一种更简单的方法,有什么想法吗?
我看过 this 但它是直线。
最后还是自己搞定了
我使用 getTangent() 和旋转计算了主曲线在其点上的 tangent 和 normal它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);
我对另一条偏移线做了同样的操作,只是反转了它的旋转,结果是这样的:
绿色 = 切线,红色 = 法线,青色 = 平行曲线
我正在尝试绘制一些 平行 曲线,一条接一条,但如果我将它们分开 modifying/translating 它们在一个轴上的位置,结果不是我要找的。
代码很简单,一个贝塞尔曲线来制作中央路径并用其他 material 克隆两侧。
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);
这是结果:
这是我正在寻找的一些示例:
最后两张图片来自 Bezier.js 库。
我认为对曲线应用偏移,或绘制另一条线使用法线[=第一个的 36=] 可能是解决方案,但我在文档中找不到任何有用的东西。 我认为也可以从切线轴或类似的距离画一条线,但这可能是一种更简单的方法,有什么想法吗?
我看过 this 但它是直线。
最后还是自己搞定了
我使用 getTangent() 和旋转计算了主曲线在其点上的 tangent 和 normal它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);
我对另一条偏移线做了同样的操作,只是反转了它的旋转,结果是这样的:
绿色 = 切线,红色 = 法线,青色 = 平行曲线