9

I'm trying to link points with a spline using Three.js for a visualization I'm trying to make.

As far as I can tell, I add points to an array, pass that to THREE.SplineCurve3, step through the spline points to get the geom coords and render. It works if I only add the start/end points to the array but if I try to add a mid-point, I get an error.

Example is here:

http://jsfiddle.net/sLQK9/4/

I'm sure it's something simple but I can't spot it - can anyone help me?

Ultimately, the points will be on the surface of a sphere and the splines between 2 points will take the route an aircraft would take - I.E. sort of great circle but further away from the center of the sphere at the midpoint of the spline.

Many thanks in advance.

bolov
  • 72,283
  • 15
  • 145
  • 224
speedwell
  • 635
  • 4
  • 9
  • 24

3 Answers3

9

I think you need to specify how many points you want the spline to interpolate the curve with, although you are specifying control points, the curve doesn't know how smooth you want it.

Try something like this:

// smooth my curve over this many points
var numPoints = 100;

spline = new THREE.SplineCurve3([
   new THREE.Vector3(0, 0, 0),
   new THREE.Vector3(0, 200, 0),
   new THREE.Vector3(150, 150, 0),
   new THREE.Vector3(150, 50, 0),
   new THREE.Vector3(250, 100, 0),
   new THREE.Vector3(250, 300, 0)
]);

var material = new THREE.LineBasicMaterial({
    color: 0xff00f0,
});

var geometry = new THREE.Geometry();
var splinePoints = spline.getPoints(numPoints);

for(var i = 0; i < splinePoints.length; i++){
    geometry.vertices.push(splinePoints[i]);  
}

var line = new THREE.Line(geometry, material);
scene.add(line);

Then, as pointed out in @juan Mellado answer, you can get a position on the line using spline.getPoint(t) where t is value between 0-1, start and end points of the spline.

As an aside, see a recent Question that was answered for me, which includes the example above.

Community
  • 1
  • 1
Neil
  • 7,861
  • 4
  • 53
  • 74
  • Also, thinking about your project, you could use the vertices from your sphere as control points for the spline! – Neil Jun 25 '12 at 08:36
9

My solution for making curves between two point in 3D scene, especially on globe:

var createCurvePath = function(start, end, elevation) {
    var start3 = globe.translateCordsToPoint(start.latitude, start.longitude);
    var end3 = globe.translateCordsToPoint(end.latitude, end.longitude);
    var mid = (new LatLon(start.latitude, start.longitude)).midpointTo(new LatLon(end.latitude, end.longitude));
    var middle3 = globe.translateCordsToPoint(mid.lat(), mid.lon(), elevation);

    var curveQuad = new THREE.QuadraticBezierCurve3(start3, middle3, end3);
    //   var curveCubic = new THREE.CubicBezierCurve3(start3, start3_control, end3_control, end3);

    var cp = new THREE.CurvePath();
    cp.add(curveQuad);
    //   cp.add(curveCubic);
    return cp;
}

then call it:

var cp = globe.createCurvePath(item1, item2, 200);
var curvedLineMaterial =  new THREE.LineBasicMaterial({color: 0xFFFFAA, linewidth: 3});
var curvedLine = new THREE.Line(cp.createPointsGeometry(20), curvedLineMaterial);
globe.scene.add(curvedLine);

note Quadratic or Cubic method of curve creation  Quadratic vs Cubic Beizer

eriegz
  • 335
  • 3
  • 10
ijavid
  • 715
  • 12
  • 23
  • I have the exact same use case but I was wondering how the commented code is calculated. For the Cubic curves. How do you proceed to compute start3_control and end3_control? – Guillaume Papin Aug 09 '13 at 00:16
  • 1
    I have some problems with calculating the correct coordinates too. Feel free do some experiments and find your correct config, finally I have chosen the Quadratic method... See it working on http://vis.jaik.sk/ (unmaintained school project) also check http://www.movable-type.co.uk/scripts/latlong.html – ijavid Aug 09 '13 at 20:36
  • 2
    https://medium.com/@xiaoyangzhao/drawing-curves-on-webgl-globe-using-three-js-and-d3-draft-7e782ffd7ab – Emile Feb 17 '20 at 18:38
3

The parameter of getPoint must be in range [0..1]:

// Virtual base class method to overwrite and implement in subclasses
//  - t [0 .. 1]

THREE.Curve.prototype.getPoint = function ( t ) {
...
Juan Mellado
  • 14,973
  • 5
  • 47
  • 54