Fork me on GitHub

verb is a JavaScript library for creating and manipulating NURBS surfaces and curves in the browser or node.js. It provides a rich set of features with many types of surfaces and curves in a 10kb (gzipped, minified) package.

Geometry

Types

See all geometry types

verb supplies a large set of routines for creating common pieces of geometry. For surfaces, these include cylinders, cones, surfaces of revolution, sweeps, extrusions. For curves, these include lines, cicles, arcs, polylines, and ellipses.

Extrusion
new verb.geom.Extrusion( profile, axis, distance);
RevolveSurface
new verb.geom.RevolveSurface( profile );
BezierCurve
new verb.geom.BezierCurve( points );

Evaluation

verb supplies methods for evaluation of points and arbitrary derivatives on NURBS curves and surfaces.

var curve = new verb.geom.BezierCurve( [p1, p2, p3, p4] );

var numDerivs = 1
	, u = 0.5;

// synchronously evaluate the point at 0.5
var point = curve.point( u );

// synchronously evaluate first derivative of the curve at 0.5
var derivs = curve.derivatives( u, numDerivs );

Tesselation

A NURBS curve or surface is an analytical function. In order to visualize it, it must be "tesselated" into a collection of lines or triangles. verb supplies naive and adaptive tesselation routines for curves and surfaces at arbitrary tolerance.

var surface = new verb.geom.NurbsSurface(  );

surface.tesselate( tesselationOptions, function(tesselation){
	...
});

Intersection

verb supplies routines for curve-surface intersection and curve-curve intersection. These algorithms can be tuned any tolerance and designed to detect multiple intersections. Algorithms for surface-surface intersection are in the works.

Intersecting a curve and surface

var srf = new verb.geom.PlanarSurface( base, uaxis, vaxis, ulength, vlength );
var crv = new verb.geom.BezierCurve( [ [5.2,5.2,5], [5.4,4.8,0], [5.2,5.2,-5] ] );
var options = { tolerance: 1e-5 };

var res = verb.intersect.curveSurface( crv, srf, options );

Asynchronous or synchronous

verb's core geometry library can be called either asynchronously or synchronously. This allows verb to be extended for multi-threading and remote evaluation.

var curve = new verb.geom.BezierCurve( [p1, p2, p3, p4] );

// tesselate the curve synchronously with default options
var pointsSync = curve.tesselate();

// tesselate the curve asynchronously (again, default options) in a background thread
curve.tesselate({}, function(points){
	...
});

Multi-threaded execution

verb uses labor.js for multi-threading using WebWorkers. If these are available, verb will automatically put them to use - potentially running multiple instances of a stateless NURBS engine. This allows expensive operations like tesselation or intersection to be elegantly handled in the background via verb's async API.

Here's an example of building an Engine and calling it directly:

// instantiate a nurbs evaluation engine
var engine = new verb.core.Engine();

// evaluate derivatives at a point along the curve
engine.eval('rational_curve_derivs', [degree, control_points, weights, knots, u, numDerivs], function(derivs){
	... do something with the derivs ...
});

Under the hood, all of verb's geometry types automatically use a background thread when calling the asynchronous API.

Reactive programming

All verb geometry types (NurbsCurve, Cone, etc) inherit from WatchObject - a prototype for watching for property changes on an object. This can be useful for operations like tesselation, where a change to the control points should cause retesselation.

var l = new verb.geom.BezierCurve( [p1, p2, p3, p4] );

var watcherId = l.watch('controlPoints', function(changeData) {
	l.tesselate(function(tesselation){

		... update view ...

	});
});

Contribute

There's still a lot of exciting work to do and I'm definitely looking for collaborators! Check out the Github page here!

verb uses the MIT License