Javascript 自定义3.Curve.create显示不正确

Javascript 自定义3.Curve.create显示不正确,javascript,three.js,Javascript,Three.js,如中所述,我创建了一条线性插值曲线,如下所示: THREE.Linear3 = THREE.Curve.create( function ( points, label /* array of Vector3 */) { this.points = (points == undefined) ? [] : points; this.label = label; }, function ( t ) { var v = new THREE.Vect

如中所述,我创建了一条线性插值曲线,如下所示:

THREE.Linear3 = THREE.Curve.create(

  function ( points, label /* array of Vector3 */) {

    this.points = (points == undefined) ? [] : points;
    this.label = label;

  },

  function ( t ) {    
    var v = new THREE.Vector3();
    var c = [];
    var points = this.points, point, intPoint, weight;
    point = ( points.length - 1 ) * t;

    intPoint = Math.floor( point );
    weight = point - intPoint;

    c[ 1 ] = intPoint;
    c[ 2 ] = intPoint  > points.length - 2 ? points.length - 1 : intPoint + 1;

    var pt1 = points[ c[1] ],
      pt2 = points[ c[2] ];

    v.copy( pt1 ).lerp( pt2, weight );

    return v;

  }

);
然而,当我试图以不同的长度(以动画的方式)显示一条轨迹时,我得到了以下行为,即曲线不是穿过点,而是穿过空间,请注意,在下面的示例中,每条轨迹都应该穿过每个球体的坐标(下面的动画gif):

我不确定我是否理解getPoint函数或者它应该返回什么。非常感谢您的帮助

JSFIDLE 这是一个很小的例子,但是你可以看到当管子膨胀时,右角的运动是如何急促的

清除一些代码 这有助于我调查这个问题

  • 如果正在泄漏几何体,则需要在从场景中删除网格后处理几何体

    scene.remove(c_mesh)
    c_tube && c_tube.dispose();
    
  • 使用WebGLRenderer。画布渲染器,并在每个帧上创建新对象。(如果你因为某种原因被画布渲染器卡住了,为你感到抱歉)

  • (对于小提琴)减慢运动,测试不需要
    requestAnimationFrame
    setTimeout(animate,500)允许用户查看正在发生的事情

  • 0段管的意义是什么

    if (index >= points.length - 1){
        index = 1; //start with 2 points
    }
    
工作如期进行
  • TubeGeometry执行N个管段(构造函数中的第二个参数,小提琴中的16个参数)。(稍后我会再讨论这个问题,但我认为您并不总是想要16段)

  • Curve.getPoinAt(TubeGeometry和许多其他几何图形使用的方法)的默认行为是返回等距点。您可以期望:
    distance(getPointAt(0)、getPointAt(0.1))==distance(getPointAt(0.1)、getPointAt(0.2))
    为真

  • 由于这些点,无论您在路径中放置了多少点,TubeGeometry都将构建一个16段的管,其中所有段的长度相同,从路径的第一个点到最后一个点。15个中间点中有一个恰好位于边位置的可能性很小。这应该可以解释你所看到的

试着修复这些东西
  • 首先,去掉管几何体+路径的等距方式。重载
    getutomapping
    应该足够了(我发现读取源代码):

  • 我更改了您的
    getPoint
    。它可能会做同样的事情,但我对我的代码更为满意

    function ( t ) {    
        var points = this.points;
        var index = ( points.length - 1 ) * t;
        var floorIndex = Math.floor(index);
        if(floorIndex == points.length-1)
            return points[floorIndex];
        var floorPoint = points[floorIndex];
        var ceilPoint = points[floorIndex+1];
        return floorPoint.clone().lerp(ceilPoint, index - floorIndex);
    }
    
  • 为TubeGeometry构造函数提供正确的段数:

    var pathPoints = points.slice(0, index);
    c_path = new THREE.Linear3(pathPoints, 'Test');
    c_tube = new THREE.TubeGeometry(c_path, pathPoints.length-1, 10, 16, false, true);
    
    在这一点上,您应该大致了解您的预期

  • 你应该看到管子总是穿过边缘。您还应该看到,管几何体并不具有角度。您可以通过查看Tube Geometry和Curve如何处理切线来改善此角度问题,或者(如果您不关心慢度)通过将分段数增加到非常大的数量来改善此问题:

    c_tube = new THREE.TubeGeometry(c_path, 200/*pathPoints.length-1*/, 10, 16, false, true);
    


答案就这些。您可以在此处找到我的实验的最新版本:。您还可以询问three.js开发人员是否存在这样的功能,或者请求在github问题中实现(如果有人愿意的话),

先生。虽然我知道您的解决方案可能有什么问题,但我们开发人员喜欢有一个JSFIDLE或任何其他类型的平台,我们可以使用它(稍后发布代码的修改版本,这是一个双赢的局面)。如果你能提供,我很乐意帮助你解决这个问题:)谢谢@Doidel为什么不自己制作小提琴呢?人们越来越懒惰,所以^^^但是我同意,如果OP将其添加到question@Doidel抱歉,刚刚看到这个,你可以看到这把小提琴的急促动作这很好,感谢你提出了切线问题,复制数字段似乎在视觉上改善了问题。嗨,沃伦,你能看看我的问题吗?我想也有类似的问题,但出于另一个原因,你能帮我解决吗?非常感谢。
c_tube = new THREE.TubeGeometry(c_path, 200/*pathPoints.length-1*/, 10, 16, false, true);