Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a spline curve between 2 points in Three.js

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.

like image 701
speedwell Avatar asked Jun 23 '12 00:06

speedwell


People also ask

How do you define spline curve?

A spline curve is a mathematical representation for which it is easy to build an interface that will allow a user to design and control the shape of complex curves and surfaces. The general approach is that the user enters a sequence of points, and a curve is constructed whose shape closely follows this sequence.


3 Answers

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.

like image 120
Neil Avatar answered Oct 08 '22 05:10

Neil


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

like image 39
ijavid Avatar answered Oct 08 '22 05:10

ijavid


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 ) {
...
like image 35
Juan Mellado Avatar answered Oct 08 '22 06:10

Juan Mellado