Javascript 在three.js中将bezier转换为平面道路

Javascript 在three.js中将bezier转换为平面道路,javascript,3d,three.js,Javascript,3d,Three.js,我试图在three.js中根据之前计算得到的一些Bezier绘制一条弯曲的道路,问题是我找不到将曲线序列(从上一条曲线的末尾开始)转换为弯曲平面的方法 我有一个3D场景,其中有一些汽车,一条用平面创建的道路,并绘制了未来道路的路径。我用我说过的Bezier曲线,将路径表示为一条带 function createAdasisBezier(initx, inity, cp1x, cp1y, cp2x, cp2y, finalx, finaly) { bezier = new THREE.Cubi

我试图在three.js中根据之前计算得到的一些Bezier绘制一条弯曲的道路,问题是我找不到将曲线序列(从上一条曲线的末尾开始)转换为弯曲平面的方法

我有一个3D场景,其中有一些汽车,一条用平面创建的道路,并绘制了未来道路的路径。我用我说过的Bezier曲线,将路径表示为一条带

function createAdasisBezier(initx, inity, cp1x, cp1y, cp2x, cp2y, finalx, finaly) {
  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)
  );
  curvePath = new THREE.CurvePath();
  curvePath.add(bezier);

  var geoPath = curvePath.createPointsGeometry( 5 );
  var lineMat = new THREE.LineBasicMaterial({color: 0xff0000});

  curveLine = new THREE.Line(geoPath, lineMat);

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

  scene.add(curveLine);
}

首先,我尝试挤出线,但后来我意识到这可能不是解决方案,因为我想做一条路,虽然我可以移动X和Y上的顶部顶点,将它们放置在贝塞尔附近,以便成为曲线的外部部分,但结果不仅不好,这也使得无法保持左曲线和右曲线之间的关系

要移动顶点(一旦确定),我执行了一个循环并手动移动它们:

for (var i = 0; i < geoPath.vertices.length; ++i) {
  geoPath.vertices[i].y += 10;
}

我尝试做的最后一件事是创建线的克隆,将其分隔几米,然后将第一个顶点从一个顶点“连接”到另一个顶点的第一个顶点,这样我就得到了一个闭合的几何体,我可以创建一个面,但我找不到如何从两个不同的几何体“连接”顶点。我尝试将顶点从一个添加到另一个,但没有成功


有人知道我怎样才能把这条线变成一条弯道吗?谢谢你的广告。

你应该试着看看这个例子。如您所见,尽管向左/向右旋转或完全循环,所有拉伸形状仍保持其宽度和方向

它们不是使用贝塞尔曲线,而是使用a来定义拉伸。如果查看,则生成红色拉伸形状的基本代码从第69行开始:

// Define the curve
var closedSpline = new THREE.CatmullRomCurve3( [
    new THREE.Vector3( -60, -100,  60 ),
    new THREE.Vector3( -60,   20,  60 ),
    new THREE.Vector3( -60,  120,  60 ),
    new THREE.Vector3(  60,   20, -60 ),
    new THREE.Vector3(  60, -100, -60 )
] );
closedSpline.type = 'catmullrom';
closedSpline.closed = true;

// Set up settings for later extrusion
var extrudeSettings = {
    steps           : 100,
    bevelEnabled    : false,
    extrudePath     : closedSpline
};

// Define a triangle
var pts = [], count = 3;
for ( var i = 0; i < count; i ++ ) {
    var l = 20;
    var a = 2 * i / count * Math.PI;
    pts.push( new THREE.Vector2 ( Math.cos( a ) * l, Math.sin( a ) * l ) );
}
var shape = new THREE.Shape( pts );

// Extrude the triangle along the CatmullRom curve
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
var material = new THREE.MeshLambertMaterial( { color: 0xb00000, wireframe: false } );

// Create mesh with the resulting geometry
var mesh = new THREE.Mesh( geometry, material );
//定义曲线
var closedSpline=新的三条CatmullRomCurve3([
新的三矢量3(-60,-100,60),
新的三个矢量3(-60,20,60),
新的三个矢量3(-60,120,60),
新的三个矢量3(60,20,-60),
新三,向量3(60,-100,-60)
] );
closedSpline.type='catmullrom';
closedSpline.closed=true;
//为以后的拉伸设置设置
变量挤出设置={
步骤:100,
bevelEnabled:错,
挤出路径:闭合样条线
};
//定义一个三角形
变量pts=[],计数=3;
对于(变量i=0;i

从这里开始,只需对这些参数进行一些小的调整即可获得所需的特定道路形状。

此页面可能会有所帮助:。它向你展示了如何在任何参数下计算bezier曲线的切线,从中你可以计算法线,从而计算道路几何坐标。它很有效,我真的很感谢你。我以前没有尝试过这一点,因为它迫使我更新我的Qt版本(它使用了Three.js的修订版71,与CatmullRomCurve不兼容,现在它是r74,我可以使用这种类型的曲线),有时似乎除了浪费一点时间更新东西之外,没有其他方法。我衷心感谢马尔科·德尔瓦勒,非常感谢你的迅速反应和好意。
// Define the curve
var closedSpline = new THREE.CatmullRomCurve3( [
    new THREE.Vector3( -60, -100,  60 ),
    new THREE.Vector3( -60,   20,  60 ),
    new THREE.Vector3( -60,  120,  60 ),
    new THREE.Vector3(  60,   20, -60 ),
    new THREE.Vector3(  60, -100, -60 )
] );
closedSpline.type = 'catmullrom';
closedSpline.closed = true;

// Set up settings for later extrusion
var extrudeSettings = {
    steps           : 100,
    bevelEnabled    : false,
    extrudePath     : closedSpline
};

// Define a triangle
var pts = [], count = 3;
for ( var i = 0; i < count; i ++ ) {
    var l = 20;
    var a = 2 * i / count * Math.PI;
    pts.push( new THREE.Vector2 ( Math.cos( a ) * l, Math.sin( a ) * l ) );
}
var shape = new THREE.Shape( pts );

// Extrude the triangle along the CatmullRom curve
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
var material = new THREE.MeshLambertMaterial( { color: 0xb00000, wireframe: false } );

// Create mesh with the resulting geometry
var mesh = new THREE.Mesh( geometry, material );