UNPKG

tuo-verb

Version:

A CAD library for the web

1,881 lines (1,247 loc) 58.2 kB
var should = require('should') , verb = require('../build/js/verb.js'); // necessary for multi-threading verb.exe.WorkerPool.basePath = process.cwd() + "/build/js/"; console.log(verb.exe.WorkerPool.basePath); // some testing utilities function vecShouldBe( expected, test, tol ){ if (tol === undefined) tol = verb.core.Constants.TOLERANCE; test.length.should.be.equal( expected.length ); for (var i = 0; i < test.length; i++){ test[i].should.be.approximately( expected[i], tol ); } } function last(a){ return a[a.length-1]; } function sameCurve( crvd0, crvd1 ){ var u0 = crvd0.knots[0]; var u1 = crvd0.knots[crvd0.knots.length-1]; var u01 = crvd1.knots[0]; var u11 = crvd1.knots[crvd1.knots.length-1]; u0.should.be.approximately(u01, 1e-10); u1.should.be.approximately(u11, 1e-10); var numSamples = 100; var step = (u1 - u0) / (numSamples-1); for (var i = 0; i < numSamples; i++ ){ var p0 = verb.eval.Eval.rationalCurvePoint( crvd0, u0 + step*i ); var p1 = verb.eval.Eval.rationalCurvePoint( crvd1, u0 + step*i ); var dist = verb.core.Vec.dist( p0, p1 ); dist.should.be.lessThan( verb.core.Constants.TOLERANCE ); } } describe("verb.geom.NurbsCurve.lengthAtParam",function(){ var degree = 3 , knots = [0,0,0,0,0.5,1,1,1,1] , controlPoints = [ [0,0,0], [1,0,0], [2,0,0], [3,0,0], [4,0,0] ] , weights = [ 1, 1, 1, 1, 1 ] , pt = [1,0.2,0.1]; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); it('is correct for basic case', function(){ var res = crv.lengthAtParam( 1 ); res.should.be.approximately(4, 1e-3 ) }); it('is correct for basic case async', function(done){ crv.lengthAtParamAsync( 1 ).then(function(res){ res.should.be.approximately(4, 1e-3 ); done(); }); }); }); describe("verb.geom.NurbsCurve.derivatives",function(){ var degree = 3 , knots = [0,0,0,0,0.5,1,1,1,1] , controlPoints = [ [0,0,0], [1,0,0], [2,0,0], [3,0,0], [4,0,0] ] , weights = [ 1, 1, 1, 1, 1 ] , pt = [1,0.2,0]; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); it('returns the derivatives for a straight curve', function(){ var p = crv.derivatives( 0.5 ); vecShouldBe( [2,0,0], p[0], 1e-3 ); vecShouldBe( [3,0,0], p[1], 1e-3 ); }); it('returns the derivatives for a straight curve async', function(done){ crv.derivativesAsync( 0.5 ).then(function(p){ vecShouldBe( [2,0,0], p[0], 1e-3 ); vecShouldBe( [3,0,0], p[1], 1e-3 ); done(); }); }); }); describe("verb.geom.NurbsCurve.tangent",function(){ var degree = 3 , knots = [0,0,0,0,0.5,1,1,1,1] , controlPoints = [ [0,0,0], [1,0,0], [2,0,0], [3,0,0], [4,0,0] ] , weights = [ 1, 1, 1, 1, 1 ] , pt = [1,0.2,0]; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); it('can get the tangent for a straight curve', function(){ var p = crv.tangent( 0.5 ); vecShouldBe( [3,0,0], p, 1e-3 ); }); it('can get the tangent for a straight curve async', function(done){ crv.tangentAsync( 0.5 ).then(function(p){ vecShouldBe( [3,0,0], p, 1e-3 ); done(); }); }); }); describe("verb.geom.NurbsCurve.paramAtLength",function(){ var degree = 3 , knots = [0,0,0,0,0.5,1,1,1,1] , controlPoints = [ [0,0,0], [1,0,0], [2,0,0], [3,0,0], [4,0,0] ] , weights = [ 1, 1, 1, 1, 1 ] , pt = [1,0.2,0]; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); it('can get closest point to straight curve', function(){ var res = crv.paramAtLength( 2 ); var p = crv.point( res ); vecShouldBe( [2,0,0], p, 1e-3 ); }); it('can get closest point to straight curve async', function(done){ crv.paramAtLengthAsync( 2 ).then(function(res){ var p = crv.point( res ); vecShouldBe( [2,0,0], p, 1e-3 ); done(); }); }); }); describe("verb.geom.NurbsCurve.divideByEqualArcLength",function(){ var degree = 3 , knots = [0,0,0,0,0.5,1,1,1,1] , controlPoints = [ [0,0,0], [1,0,0], [2,0,0], [3,0,0], [4,0,0] ] , weights = [ 1, 1, 1, 1, 1 ] , divs = 10 , d = 4 / divs; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); it('can divide straight curve', function(){ var res = crv.divideByEqualArcLength( divs ); var tol = 1e-3; var s = 0; res.forEach(function(u){ var pt = crv.point( u.u ); u.len.should.be.approximately( s, tol ); pt[0].should.be.approximately( s, tol ); s += d; }); }); it('can divide straight curve async', function(done){ crv.divideByEqualArcLengthAsync( divs ).then(function(res){ var tol = 1e-3; var s = 0; res.forEach(function(u){ var pt = crv.point( u.u ); u.len.should.be.approximately( s, tol ); pt[0].should.be.approximately( s, tol ); s += d; }); done(); }) }); }); describe("verb.geom.NurbsCurve.divideByArcLength",function(){ var degree = 3 , knots = [0,0,0,0,0.5,1,1,1,1] , controlPoints = [ [0,0,0], [1,0,0], [2,0,0], [3,0,0], [4,0,0] ] , weights = [ 1, 1, 1, 1, 1 ] , divs = 10 , d = 4 / divs; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); var tol = 1e-3; it('can divide straight curve', function(){ var res = crv.divideByArcLength( d ); var s = 0; res.forEach(function(u){ var pt = crv.point( u.u ); u.len.should.be.approximately( s, tol ); pt[0].should.be.approximately( s, tol ); s += d; }); }); it('can divide straight curve async', function(){ crv.divideByArcLengthAsync( d ).then(function(res){ var s = 0; res.forEach(function(u){ var pt = crv.point( u.u ); u.len.should.be.approximately( s, tol ); pt[0].should.be.approximately( s, tol ); s += d; }); }) }); }); describe("verb.geom.NurbsCurve.closestParam",function(){ var degree = 3 , knots = [0,0,0,0,0.5,1,1,1,1] , controlPoints = [ [0,0,0], [1,0,0], [2,0,0], [3,0,0], [4,0,0] ] , weights = [ 1, 1, 1, 1, 1 ]; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); it('can get point on straight curve', function(){ var pt = [1,0,0]; var res = crv.closestParam( pt ); var p = crv.point( res ); vecShouldBe( [1,0,0], p, 1e-3 ); }); it('can get closest point to straight curve', function(){ var pt = [1,1,0]; var res = crv.closestParam(pt); var p = crv.point( res ); vecShouldBe( [1,0,0], p, 1e-3 ); }); it('can get closest point to straight curve async', function(done){ var pt = [1,1,0]; crv.closestParamAsync(pt).then(function(res){ var p = crv.point( res ); vecShouldBe( [1,0,0], p, 1e-3 ); done(); }); }); it('can get point on straight curve of degree 1', function() { var degree = 1 , knots = [0, 0, 1, 1] , controlPoints = [[0,0,0], [10,0,0]] , weights = [1, 1]; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights(degree, knots, controlPoints, weights); var pt = [5,0,0]; var res = crv.closestParam( pt ); var p = crv.point( res ); vecShouldBe([5,0,0], p, 1e-3); }); }); describe("verb.geom.NurbsCurve.split",function(){ var degree = 3 , knots = [ 0, 0, 0, 0, 1, 2, 3, 4, 5, 5, 5, 5 ]; var controlPoints = []; var weights = []; for (var i = 0; i < 8; i++) { weights.push(1); controlPoints.push([i, 0, 0]); } var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); function cubicSplitAsync(u, done){ var res = crv.splitAsync(0.5); check(u, res); } function check(u, res){ var crv0 = res[0]; var crv1 = res[1]; // a point evaluated on each curve is the same var p0 = crv0.point(crv0.domain().max); var p1 = crv1.point(crv1.domain().min); p0[0].should.be.approximately(p1[0], verb.core.Constants.TOLERANCE); p0[1].should.be.approximately(p1[1], verb.core.Constants.TOLERANCE); p0[2].should.be.approximately(p1[2], verb.core.Constants.TOLERANCE); } it('returns expected results when splitting curve', function(){ var res = crv.split( 2.5 ); check(2.5, res); }); it('returns expected results when splitting curve async', function(done){ crv.splitAsync( 2.5 ).then(function(res){ check(2.5, res); done(); }); }); }); describe("verb.geom.NurbsCurve.transform",function(){ var degree = 3 , knots = [0,0,0,0,0.5,1,1,1,1] , controlPoints = [ [0,0,0], [1,0,0], [2,0,0], [3,0,0], [4,0,0] ] , weights = [ 1, 1, 1, 1, 1 ]; var t = [ [ 1, 0, 0, 5 ], [ 0, 1, 0, 2 ], [ 0, 0, 1, -1], [ 0, 0, 0, 1 ] ]; var crv = verb.geom.NurbsCurve.byKnotsControlPointsWeights( degree, knots, controlPoints, weights ); it('works for basic case', function(){ var ta = crv.transform( t ); ta.point( 0.5 ).should.be.eql([2 + 5, 2, -1 ]); }); it('works for basic case async', function(done){ crv.transformAsync( t ).then(function(ta){ ta.point( 0.5 ).should.be.eql([2 + 5, 2, -1 ]); done(); }); }); }); describe("verb.geom.Arc.constructor",function(){ it('has correct properties', function(){ var arc = new verb.geom.Arc([0,0,0], [1,0,0], [0,1,0], 5, 0, Math.PI/ 2 ); should.exist( arc ); arc.radius().should.be.equal(5); arc.center().should.eql([0,0,0]); arc.xaxis().should.eql([1,0,0]); arc.yaxis().should.eql([0,1,0]); arc.minAngle().should.be.equal(0); arc.maxAngle().should.be.equal(Math.PI/2); }); }); describe("verb.geom.Arc.point",function(){ it('returns expected results', function(){ var arc = new verb.geom.Arc([0,0,1], [1,0,0], [0,1,0], 1, 0, Math.PI/ 2 ); var p1 = arc.point(0); var p2 = arc.point(0.5); var p3 = arc.point(1); p1.should.be.instanceof(Array).and.have.lengthOf(3); p1[0].should.be.approximately( 1, 0.001 ); p1[1].should.be.approximately( 0, 0.001 ); p1[2].should.be.approximately( 1, 0.001 ); p2.should.be.instanceof(Array).and.have.lengthOf(3); p2[0].should.be.approximately( Math.sqrt(2)/2, 0.001 ); p2[1].should.be.approximately( Math.sqrt(2)/2, 0.001 ); p2[2].should.be.approximately( 1, 0.001 ); p3.should.be.instanceof(Array).and.have.lengthOf(3); p3[0].should.be.approximately( 0, 0.001 ); p3[1].should.be.approximately( 1, 0.001 ); p3[2].should.be.approximately( 1, 0.001 ); }); it('creates the expected result when given a callback', function(done){ var arc = new verb.geom.Arc([0,0,1], [1,0,0], [0,1,0], 1, 0, Math.PI/ 2 ); arc.pointAsync(0.5).then(function(res){ res.should.be.instanceof(Array).and.have.lengthOf(3); res[0].should.be.approximately( Math.sqrt(2)/2, 0.001 ); res[1].should.be.approximately( Math.sqrt(2)/2, 0.001 ); res[2].should.be.approximately( 1, 0.001 ); done(); }); }); }); describe("verb.geom.Arc.tessellate",function(){ it('should return a list of vertices', function(){ var arc = new verb.geom.Arc([0,0,1], [1,0,0], [0,1,0], 1, 0, Math.PI/ 2 ); var pts = arc.tessellate(); pts.length.should.be.greaterThan(2); pts.map( function(e){ e.length.should.be.equal(3); }); }); }); describe("new verb.geom.Line",function(){ it('can create an instance', function(){ var p1 = [0,0,1] , p2 = [1,0,0]; var c = new verb.geom.Line( p1, p2 ); should.exist(c); }); }); describe("verb.geom.Line.point",function(){ it('evaluates correctly', function(){ var p1 = [0,0,0] , p2 = [1,1,1]; var c = new verb.geom.Line( p1, p2 ); should.exist(c); var p = c.point(0.5); p[0].should.be.approximately(0.5, verb.core.Constants.EPSILON ); p[1].should.be.approximately(0.5, verb.core.Constants.EPSILON ); p[2].should.be.approximately(0.5, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.Line.derivatives",function(){ it('gives nice result', function(){ var p1 = [0,0,0] , p2 = [1,1,1]; var c = new verb.geom.Line( p1, p2 ); should.exist(c); var p = c.derivatives(0.5, 1); p[0].should.eql([0.5,0.5,0.5]); p[1].should.eql([1,1,1]); }); }); describe("verb.geom.Line.tessellate",function(){ it('gives mesh result', function(){ var p1 = [0,0,0] , p2 = [1,1,1]; var c = new verb.geom.Line( p1, p2 ); should.exist(c); var p = c.tessellate(); p.length.should.be.equal(2); p[0].length.should.be.equal(3); p[1].length.should.be.equal(3); }); }); describe("verb.geom.BezierCurve.constructor",function(){ it('can create an instance', function(){ var p1 = [0,0,0] , p2 = [1,0,1] , p3 = [2,0,-1] , p4 = [3,0,0]; var c = new verb.geom.BezierCurve( [p1, p2, p3, p4] ); should.exist(c); }); }); describe("verb.geom.BezierCurve.point",function(){ it('evaluates correctly', function(){ var p1 = [0,0,0] , p2 = [1,0,1] , p3 = [2,0,-1] , p4 = [3,0,0]; var c = new verb.geom.BezierCurve( [p1, p2, p3, p4] ); should.exist(c); var p = c.point(0.5); p.should.eql([1.5,0,0]); }); }); describe("verb.geom.BezierCurve.derivatives",function(){ it('gives nice result', function(){ var p1 = [0,0,0] , p2 = [1,0,1] , p3 = [2,0,-1] , p4 = [3,0,0]; var c = new verb.geom.BezierCurve( [p1, p2, p3, p4] ); should.exist(c); var p = c.derivatives(0.5, 1); p[0].should.eql([1.5,0,0]); p[1].should.eql([3, 0, -1.5]); }); }); describe("verb.geom.BezierCurve.tessellate",function(){ it('gives mesh result', function(){ var p1 = [0,0,0] , p2 = [1,0,1] , p3 = [2,0,-1] , p4 = [3,0,0]; var c = new verb.geom.BezierCurve( [p1, p2, p3, p4] ); should.exist(c); var pts = c.tessellate(); pts.length.should.be.greaterThan(2); pts.map( function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.Circle.constructor",function(){ it('can create an instance', function(){ var c = new verb.geom.Circle([0,0,0], [1,0,0], [0,1,0], 5); should.exist(c); }); }); describe("verb.geom.Circle.point",function(){ it('evaluates correctly', function(){ var c = new verb.geom.Circle([0,0,0], [1,0,0], [0,1,0], 5); should.exist(c); var p = c.point(0.5); p[0].should.be.approximately(-5, verb.core.Constants.TOLERANCE ); p[1].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); }); }); describe("verb.geom.Circle.derivatives",function(){ it('gives correct result', function(){ var c = new verb.geom.Circle([0,0,0], [1,0,0], [0,1,0], 5); should.exist(c); var p = c.derivatives(0.5, 1); p[0][0].should.be.approximately(-5, verb.core.Constants.TOLERANCE ); p[0][1].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[0][2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); // normalize the derivative p[1] = verb.core.Vec.div( p[1], verb.core.Vec.norm(p[1]) ); p[1][0].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[1][1].should.be.approximately(-1, verb.core.Constants.TOLERANCE ); p[1][2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); }); }); describe("verb.geom.Circle.tessellate",function(){ it('gives correct result', function(){ var c = new verb.geom.Circle([0,0,0], [1,0,0], [0,1,0], 5); should.exist(c); var pts = c.tessellate(); pts.length.should.be.greaterThan(2); pts.map( function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.Ellipse.constructor",function(){ it('can create an instance', function(){ var c = new verb.geom.Ellipse([0,0,0], [5,0,0], [0,10,0]); should.exist(c); }); }); describe("verb.geom.Ellipse.point",function(){ it('evaluates correctly', function(){ var c = new verb.geom.Ellipse([0,0,0], [5,0,0], [0,10,0]); should.exist(c); var p = c.point(0.5); p[0].should.be.approximately(-5, verb.core.Constants.TOLERANCE ); p[1].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); var p = c.point(0.25); p[0].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[1].should.be.approximately(10, verb.core.Constants.TOLERANCE ); p[2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); }); }); describe("verb.geom.Ellipse.derivatives",function(){ it('gives correct result', function(){ var c = new verb.geom.Ellipse([0,0,0], [5,0,0], [0,10,0]); should.exist(c); var p = c.derivatives(0.5, 1); p[0][0].should.be.approximately(-5, verb.core.Constants.TOLERANCE ); p[0][1].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[0][2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); // normalize the derivative p[1] = verb.core.Vec.div( p[1], verb.core.Vec.norm(p[1]) ); p[1][0].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[1][1].should.be.approximately(-1, verb.core.Constants.TOLERANCE ); p[1][2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p = c.derivatives(0.25, 1); p[0][0].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[0][1].should.be.approximately(10, verb.core.Constants.TOLERANCE ); p[0][2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); // normalize the derivative p[1] = verb.core.Vec.div( p[1], verb.core.Vec.norm(p[1]) ); p[1][0].should.be.approximately(-1, verb.core.Constants.TOLERANCE ); p[1][1].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[1][2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); }); }); describe("verb.geom.Ellipse.tessellate",function(){ it('gives correct result', function(){ var c = new verb.geom.Ellipse([0,0,0], [5,0,0], [0,10,0]); should.exist(c); var pts = c.tessellate(); pts.length.should.be.greaterThan(2); pts.map( function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.EllipseArc.constructor",function(){ it('can create an instance', function(){ var c = new verb.geom.EllipseArc([0,0,0], [1,0,0], [0,1,0], 0, Math.PI); should.exist(c); }); }); describe("verb.geom.EllipseArc.point",function(){ it('evaluates correctly', function(){ var c = new verb.geom.EllipseArc([0,0,0], [1,0,0], [0,10,0], 0, Math.PI); should.exist(c); var p = c.point(0.5); p[0].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[1].should.be.approximately(10, verb.core.Constants.TOLERANCE ); p[2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); }); }); describe("verb.geom.EllipseArc.derivatives",function(){ it('gives correct result', function(){ var c = new verb.geom.EllipseArc([0,0,0], [1,0,0], [0,10,0], 0, Math.PI); should.exist(c); var p = c.derivatives(0.5, 1); p[0][0].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[0][1].should.be.approximately(10, verb.core.Constants.TOLERANCE ); p[0][2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); // normalize the derivative p[1] = verb.core.Vec.div( p[1], verb.core.Vec.norm(p[1]) ); p[1][0].should.be.approximately(-1, verb.core.Constants.TOLERANCE ); p[1][1].should.be.approximately(0, verb.core.Constants.TOLERANCE ); p[1][2].should.be.approximately(0, verb.core.Constants.TOLERANCE ); }); }); describe("verb.geom.EllipseArc.tessellate",function(){ it('gives correct result', function(){ var c = new verb.geom.EllipseArc([0,0,0], [1,0,0], [0,10,0], 0, Math.PI); should.exist(c); var pts = c.tessellate(); pts.length.should.be.greaterThan(2); pts.map( function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.NurbsSurface.byKnotsControlPointsWeights",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('has expected properties', function(){ surface.degreeU().should.be.equal( 3 ); surface.degreeV().should.be.equal( 3 ); surface.knotsU().should.be.eql( knotsU ); surface.knotsV().should.be.eql( knotsV ); surface.controlPoints().should.be.eql( controlPoints ); surface.weights().should.be.eql( weights ); }); }); describe("verb.geom.NurbsSurface.domainU",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case', function(){ var d = surface.domainU(); d.min.should.be.equal( 0 ); d.max.should.be.equal( 1 ); }); }); describe("verb.geom.NurbsSurface.domainV",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 2, 2, 2, 2] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case', function(){ var d = surface.domainU(); d.min.should.be.equal( 0 ); d.max.should.be.equal( 1 ); }); }); describe("verb.geom.NurbsSurface.point",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case', function(){ vecShouldBe( [15, -15, 0], surface.point(0.5,0.5) ); }); it('is correct for basic case async', function(done){ surface.pointAsync(0.5,0.5).then(function(x){ vecShouldBe( [15, -15, 0], x ); done(); }); }); }); describe("verb.geom.NurbsSurface.normal",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case', function(){ vecShouldBe( [0, 0, 900], surface.normal(0.5,0.5) ); }); it('is correct for basic case async', function(done){ surface.normalAsync(0.5,0.5).then(function(x){ vecShouldBe( [0, 0, 900], x ); done(); }); }); }); describe("verb.geom.NurbsSurface.derivatives",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case', function(){ var d = surface.derivatives( 0.5, 0.5, 1 ); vecShouldBe( [15, -15, 0], d[0][0] ); vecShouldBe( [0, -30, 0], d[1][0] ); vecShouldBe( [30, 0, 0], d[0][1] ); }); it('is correct for basic case async', function(done){ surface.derivativesAsync( 0.5, 0.5, 1 ).then(function(d){ vecShouldBe( [15, -15, 0], d[0][0] ); vecShouldBe( [0, -30, 0], d[1][0] ); vecShouldBe( [30, 0, 0], d[0][1] ); done(); }); }); }); describe("verb.geom.NurbsSurface.closestParam",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case', function(){ var d = surface.closestParam( [ 15, -15, 1] ); vecShouldBe( [0.5, 0.5], d ); }); it('is correct for basic case async', function(done){ surface.closestParamAsync( [15, -15, 1] ).then(function(d){ vecShouldBe( [0.5, 0.5], d ); done(); }); }); it('is correct for basic case of degree 1 in both directions', function() { var degreeU = 1 , degreeV = 1 , knotsU = [0, 0, 1, 1] , knotsV = [0, 0, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0] ], [ [0, 20, 0], [10, 20, 0] ] ] , weights = [ [ 1, 1 ], [ 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); var d = surface.closestParam( [ 5, 10, 1] ); vecShouldBe( [0.5, 0.5], d ); }); it('is correct for basic case of degree 1 in one direction', function() { var degreeU = 1 , degreeV = 2 , knotsU = [0, 0, 1, 1] , knotsV = [0, 0, 0, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [5, 0, 0], [10, 0, 0] ], [ [0, 20, 0], [5, 20, 0], [10, 20, 0] ] ] , weights = [ [ 1, 1, 1], [ 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); var d = surface.closestParam( [ 5, 10, 1] ); vecShouldBe( [0.5, 0.5], d ); }); }); describe("verb.geom.NurbsSurface.closestPoint",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case', function(){ var d = surface.closestPoint( [ 15, -15, 1] ); vecShouldBe( [15, -15, 0], d ); }); it('is correct for basic case async', function(done){ surface.closestPointAsync( [15, -15, 1] ).then(function(d){ vecShouldBe( [15, -15, 0], d ); done(); }); }); }); describe("verb.geom.NurbsSurface.split",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case 1', function(){ var d = surface.split( 0.5, true ); d[0].domainV().min.should.be.equal(0); d[0].domainV().max.should.be.equal(0.5); d[0].domainU().min.should.be.equal(0); d[0].domainU().max.should.be.equal(1.0); d[1].domainV().min.should.be.equal(0.5); d[1].domainV().max.should.be.equal(1.0); d[1].domainU().min.should.be.equal(0); d[1].domainU().max.should.be.equal(1.0); }); it('is correct for basic case 2', function(){ var d = surface.split( 0.5, false ); d[0].domainV().min.should.be.equal(0); d[0].domainV().max.should.be.equal(1.0); d[0].domainU().min.should.be.equal(0); d[0].domainU().max.should.be.equal(0.5); d[1].domainV().min.should.be.equal(0); d[1].domainV().max.should.be.equal(1.0); d[1].domainU().min.should.be.equal(0.5); d[1].domainU().max.should.be.equal(1.0); }); it('is correct for basic case async', function(done){ surface.splitAsync( 0.5, true ).then(function(d){ d[0].domainV().min.should.be.equal(0); d[0].domainV().max.should.be.equal(0.5); d[0].domainU().min.should.be.equal(0); d[0].domainU().max.should.be.equal(1.0); d[1].domainV().min.should.be.equal(0.5); d[1].domainV().max.should.be.equal(1.0); d[1].domainU().min.should.be.equal(0); d[1].domainU().max.should.be.equal(1.0); done(); }); }); }); describe("verb.geom.NurbsSurface.tessellate",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); it('is correct for basic case with no options', function(){ var d = surface.tessellate(); d.faces.length.should.be.greaterThan( 2 ); d.normals.length.should.be.greaterThan( 2 ); d.points.length.should.be.greaterThan( 2 ); d.uvs.length.should.be.greaterThan( 2 ); }); // it('is correct for basic case async', function(done){ // surface.tessellateAsync( 0.5, true ).then(function(d){ // console.log("Hello"); // // d.faces.length.should.be.greaterThan( 2 ); // d.normals.length.should.be.greaterThan( 2 ); // d.points.length.should.be.greaterThan( 2 ); // d.uvs.length.should.be.greaterThan( 2 ); // // done(); // }); // }); }); describe("verb.geom.NurbsSurface.transform",function(){ var degreeU = 3 , degreeV = 3 , knotsU = [0, 0, 0, 0, 1, 1, 1, 1] , knotsV = [0, 0, 0, 0, 1, 1, 1, 1] , controlPoints = [ [ [0, 0, 0], [10, 0, 0], [20, 0, 0], [30, 0, 0] ], [ [0, -10, 0], [10, -10, 0], [20, -10, 0], [30, -10, 0] ], [ [0, -20, 0], [10, -20, 0], [20, -20, 0], [30, -20, 0] ], [ [0, -30, 0], [10, -30, 0], [20, -30, 0], [30, -30, 0] ] ] , weights = [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ] , surface = verb.geom.NurbsSurface.byKnotsControlPointsWeights( degreeU, degreeV, knotsU, knotsV, controlPoints, weights ); var t = [ [ 1, 0, 0, 5 ], [ 0, 1, 0, 2 ], [ 0, 0, 1, -1], [ 0, 0, 0, 1 ] ]; it('is correct for basic case with no options', function(){ var ta = surface.transform( t ); ta.point(0.5,0.5).should.be.eql( [ 15 + 5, -15 + 2, 0 - 1] ); }); it('is correct for basic case async', function(done){ surface.transformAsync( t ).then(function(ta){ ta.point(0.5,0.5).should.be.eql( [ 15 + 5, -15 + 2, 0 - 1] ); done(); }); }); }); describe("verb.geom.NurbsCurve.byPoints",function(){ function shouldInterpPoints(curve, pts){ // // the internal points are interped var tess = curve.tessellate( 1e-8 ); for (var j = 0; j < pts.length; j++){ var min = Number.MAX_VALUE; for (var i = 1; i < tess.length; i++){ var pt = pts[j]; var o = tess[i-1]; var r = verb.core.Vec.normalized( verb.core.Vec.sub( tess[i], tess[i-1] ) ); var dist = verb.core.Trig.distToRay( pt, o, r ); if (dist < min) { min = dist; } } min.should.be.lessThan( 1e-3 ); } } var pts = [ [0, 0, 1], [3,4, 0], [-1,4, 0], [-4,0, 0], [-4,-3, 0] ]; it('can compute valid cubic interpolating curve for 4 points', function(){ shouldInterpPoints( verb.geom.NurbsCurve.byPoints( pts ), pts ); }); }); describe("verb.geom.ExtrudedSurface",function(){ it('can create an instance', function(){ var profile = new verb.geom.Line( [0,0,0], [1,1,1] ) , axis = [0,0,1] , length = 3; var srf = new verb.geom.ExtrudedSurface( profile, axis, length); should.exist(srf); }); }); describe("verb.geom.ExtrudedSurface.point",function(){ it('evaluates correctly for middle of surface', function(){ var profile = new verb.geom.Line( [0,0,0], [1,1,0] ) , axis = [0,0,3]; var srf = new verb.geom.ExtrudedSurface( profile, axis ); should.exist(srf); var p = srf.point(0.5,0.5); p[0].should.be.approximately(0.5, verb.core.Constants.EPSILON ); p[1].should.be.approximately(0.5, verb.core.Constants.EPSILON ); p[2].should.be.approximately(1.5, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.ExtrudedSurface.derivatives",function(){ it('gives expected result for middle of surface', function(){ var profile = new verb.geom.Line( [0,0,0], [1,1,0] ) , axis = [0,0,3]; var srf = new verb.geom.ExtrudedSurface( profile, axis ); should.exist(srf); var p = srf.derivatives(0.5, 0.5, 1); p[0][0][0].should.be.approximately(0.5, verb.core.Constants.EPSILON ); p[0][0][1].should.be.approximately(0.5, verb.core.Constants.EPSILON ); p[0][0][2].should.be.approximately(1.5, verb.core.Constants.EPSILON ); p[0][1][0].should.be.approximately(1, verb.core.Constants.EPSILON ); p[0][1][1].should.be.approximately(1, verb.core.Constants.EPSILON ); p[0][1][2].should.be.approximately(0, verb.core.Constants.EPSILON ); p[1][0][0].should.be.approximately(0, verb.core.Constants.EPSILON ); p[1][0][1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[1][0][2].should.be.approximately(-3, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.ExtrudedSurface.tessellate",function(){ it('gives mesh result', function(){ var profile = new verb.geom.Line( [0,0,0], [1,1,0] ) , axis = [0,0,3]; var srf = new verb.geom.ExtrudedSurface( profile, axis ); should.exist(srf); var p = srf.tessellate(); p.uvs.length.should.be.greaterThan(10); p.points.length.should.be.greaterThan(10); p.faces.length.should.be.greaterThan(10); p.normals.length.should.be.greaterThan(10); p.points.map(function(e){ e.length.should.be.equal(3); }); p.uvs.map(function(e){ e.length.should.be.equal(2); }); p.faces.map(function(e){ e.length.should.be.equal(3); }); p.normals.map(function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.RevolvedSurface.constructor",function(){ it('can create an instance', function(){ var base = [0,0,0] , axis = [0,0,1] , angle = Math.PI , profile = new verb.geom.Line( [1, 0, 10], [10, 0, 1] ); var srf = new verb.geom.RevolvedSurface( profile, base, axis, angle ); should.exist(srf); }); }); describe("verb.geom.RevolvedSurface.point",function(){ it('evaluates correctly for middle of surface', function(){ var base = [0,0,0] , axis = [0,0,1] , angle = Math.PI , profile = new verb.geom.Line( [1, 0, 10], [10, 0, 1] ); var srf = new verb.geom.RevolvedSurface( profile, base, axis, angle ); should.exist(srf); var p = srf.point(0.5,0.5); p[0].should.be.approximately(0, verb.core.Constants.EPSILON ); p[1].should.be.approximately(5.5, verb.core.Constants.EPSILON ); p[2].should.be.approximately(5.5, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.RevolvedSurface.derivatives",function(){ it('gives expected result for middle of surface', function(){ var base = [0,0,0] , axis = [0,0,1] , angle = Math.PI , profile = new verb.geom.Line( [1, 0, 10], [10, 0, 1] ); var srf = new verb.geom.RevolvedSurface( profile, base, axis, angle ); should.exist(srf); var p = srf.derivatives(0.5, 0.5, 1); p[0][0][0].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][0][1].should.be.approximately(5.5, verb.core.Constants.EPSILON ); p[0][0][2].should.be.approximately(5.5, verb.core.Constants.EPSILON ); p[0][1][0].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][1][1].should.be.approximately(9, verb.core.Constants.EPSILON ); p[0][1][2].should.be.approximately(-9, verb.core.Constants.EPSILON ); p[1][0] = verb.core.Vec.normalized( p[1][0] ); p[1][0][0].should.be.approximately(-1, verb.core.Constants.EPSILON ); p[1][0][1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[1][0][2].should.be.approximately(0, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.RevolvedSurface.tessellate",function(){ it('gives mesh result', function(){ var base = [0,0,0] , axis = [0,0,1] , angle = Math.PI , profile = new verb.geom.Line( [1, 0, 10], [10, 0, 1] ); var srf = new verb.geom.RevolvedSurface( profile, base, axis, angle ); should.exist(srf); var p = srf.tessellate(); p.uvs.length.should.be.greaterThan(10); p.points.length.should.be.greaterThan(10); p.faces.length.should.be.greaterThan(10); p.normals.length.should.be.greaterThan(10); p.points.map(function(e){ e.length.should.be.equal(3); }); p.uvs.map(function(e){ e.length.should.be.equal(2); }); p.faces.map(function(e){ e.length.should.be.equal(3); }); p.normals.map(function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.SphericalSurface.constructor",function(){ it('can create an instance', function(){ var center = [0,0,0] , radius = 5; var srf = new verb.geom.SphericalSurface( center, radius ); should.exist(srf); srf.center().should.eql( center ); srf.radius().should.eql( radius ); }); }); describe("verb.geom.SphericalSurface.point",function(){ it('evaluates correctly for middle of surface', function(){ var center = [0,0,0] , radius = 5; var srf = new verb.geom.SphericalSurface( center, radius ); should.exist(srf); var p = srf.point(0.5,0.5); p[0].should.be.approximately(-radius, verb.core.Constants.EPSILON ); p[1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[2].should.be.approximately(0, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.SphericalSurface.derivatives",function(){ it('gives expected result for middle of surface', function(){ var center = [0,0,0] , radius = 5; var srf = new verb.geom.SphericalSurface( center, radius ); should.exist(srf); var p = srf.derivatives(0.5, 0.5, 1); p[0][0][0].should.be.approximately(-radius, verb.core.Constants.EPSILON ); p[0][0][1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][0][2].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][1] = verb.core.Vec.normalized( p[0][1] ); p[0][1][0].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][1][1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][1][2].should.be.approximately(1, verb.core.Constants.EPSILON ); p[1][0] = verb.core.Vec.normalized( p[1][0] ); p[1][0][0].should.be.approximately(0, verb.core.Constants.EPSILON ); p[1][0][1].should.be.approximately(-1, verb.core.Constants.EPSILON ); p[1][0][2].should.be.approximately(0, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.SphericalSurface.tessellate",function(){ it('gives mesh result', function(){ var center = [0,0,0] , radius = 5; var srf = new verb.geom.SphericalSurface( center, radius ); should.exist(srf); var p = srf.tessellate(); p.uvs.length.should.be.greaterThan(10); p.points.length.should.be.greaterThan(10); p.faces.length.should.be.greaterThan(10); p.normals.length.should.be.greaterThan(10); p.points.map(function(e){ e.length.should.be.equal(3); }); p.uvs.map(function(e){ e.length.should.be.equal(2); }); p.faces.map(function(e){ e.length.should.be.equal(3); }); p.normals.map(function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.CylindricalSurface.constructor",function(){ it('can create an instance', function(){ var axis = [0,0,1] , xaxis = [1,0,0] , base = [0,0,0] , height = 5 , radius = 3; var srf = new verb.geom.CylindricalSurface( axis, xaxis, base, height, radius ); should.exist(srf); srf.axis().should.eql( axis ); srf.xaxis().should.eql( xaxis ); srf.base().should.eql( base ); srf.height().should.eql( height ); srf.radius().should.eql( radius ); }); }); describe("verb.geom.CylindricalSurface.point",function(){ it('evaluates correctly for middle of surface', function(){ var axis = [0,0,1] , xaxis = [1,0,0] , base = [0,0,0] , height = 5 , radius = 3; var srf = new verb.geom.CylindricalSurface( axis, xaxis, base, height, radius ); console.log( srf.serialize() ); should.exist(srf); var p = srf.point(0.5,0.5); p[0].should.be.approximately(-3, verb.core.Constants.EPSILON ); p[1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[2].should.be.approximately(2.5, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.CylindricalSurface.derivatives",function(){ it('gives expected result for middle of surface', function(){ var axis = [0,0,1] , xaxis = [1,0,0] , base = [0,0,0] , height = 5 , radius = 3; var srf = new verb.geom.CylindricalSurface( axis, xaxis, base, height, radius ); should.exist(srf); var p = srf.derivatives(0.5, 0.5, 1); p[0][0][0].should.be.approximately(-3, verb.core.Constants.EPSILON ); p[0][0][1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][0][2].should.be.approximately(2.5, verb.core.Constants.EPSILON ); p[1][0][0].should.be.approximately(0, verb.core.Constants.EPSILON ); p[1][0][1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[1][0][2].should.be.approximately(-5, verb.core.Constants.EPSILON ); p[0][1] = verb.core.Vec.div( p[0][1], verb.core.Vec.norm(p[0][1]) ); p[0][1][0].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][1][1].should.be.approximately(-1, verb.core.Constants.EPSILON ); p[0][1][2].should.be.approximately(0, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.CylindricalSurface.tessellate",function(){ it('gives mesh result', function(){ var axis = [0,0,1] , xaxis = [1,0,0] , base = [0,0,0] , height = 5 , radius = 3; var srf = new verb.geom.CylindricalSurface( axis, xaxis, base, height, radius ); should.exist(srf); var p = srf.tessellate(); p.uvs.length.should.be.greaterThan(10); p.points.length.should.be.greaterThan(10); p.faces.length.should.be.greaterThan(10); p.normals.length.should.be.greaterThan(10); p.points.map(function(e){ e.length.should.be.equal(3); }); p.uvs.map(function(e){ e.length.should.be.equal(2); }); p.faces.map(function(e){ e.length.should.be.equal(3); }); p.normals.map(function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.NurbsSurface.byCorners",function(){ it('can create an instance', function(){ var p1 = [0,0,1] , p2 = [1,0,0] , p3 = [1,1,1] , p4 = [0,1,0]; var srf = verb.geom.NurbsSurface.byCorners( p1, p2, p3, p4 ); should.exist(srf); }); }); describe("verb.geom.NurbsSurface.byCorners -> verb.geom.NurbsSurface.point",function(){ it('evaluates correctly for hypar', function(){ var p1 = [0,0,1] , p2 = [1,0,0] , p3 = [1,1,1] , p4 = [0,1,0]; var srf = verb.geom.NurbsSurface.byCorners( p1, p2, p3, p4 ); should.exist(srf); var p = srf.point(0.5,0.5); p[0].should.be.approximately(0.5, verb.core.Constants.EPSILON ); p[1].should.be.approximately(0.5, verb.core.Constants.EPSILON ); p[2].should.be.approximately(0.5, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.NurbsSurface.byCorners -> verb.geom.NurbsSurface.derivatives",function(){ it('gives nice result', function(){ var p1 = [0,0,1] , p2 = [1,0,0] , p3 = [1,1,1] , p4 = [0,1,0]; var srf = verb.geom.NurbsSurface.byCorners( p1, p2, p3, p4 ); should.exist(srf); var p = srf.derivatives(0.5, 0.5, 1); vecShouldBe( [0.5,0.5,0.5], p[0][0] ); vecShouldBe( [0,1,0], p[0][1] ); vecShouldBe( [1,0,0], p[1][0] ); }); }); describe("verb.geom.NurbsSurface.byCorners -> verb.geom.NurbsSurface.tessellate",function(){ it('gives mesh result', function(){ var p1 = [0,0,1] , p2 = [1,0,0] , p3 = [1,1,1] , p4 = [0,1,0]; var srf = verb.geom.NurbsSurface.byCorners( p1, p2, p3, p4 ); should.exist(srf); var p = srf.tessellate(); p.uvs.length.should.be.greaterThan(10); p.points.length.should.be.greaterThan(10); p.faces.length.should.be.greaterThan(10); p.normals.length.should.be.greaterThan(10); p.points.map(function(e){ e.length.should.be.equal(3); }); p.uvs.map(function(e){ e.length.should.be.equal(2); }); p.faces.map(function(e){ e.length.should.be.equal(3); }); p.normals.map(function(e){ e.length.should.be.equal(3); }); }); }); describe("verb.geom.ConicalSurface.constructor",function(){ it('can create an instance', function(){ var axis = [0,0,1] , xaxis = [1,0,0] , base = [0,0,0] , height = 5 , radius = 3; var srf = new verb.geom.ConicalSurface( axis, xaxis, base, height, radius ); should.exist(srf); srf.axis().should.eql( axis ); srf.xaxis().should.eql( xaxis ); srf.base().should.eql( base ); srf.height().should.eql( height ); srf.radius().should.eql( radius ); }); }); describe("verb.geom.ConicalSurface.point",function(){ it('evaluates correctly for middle of surface', function(){ var axis = [0,0,1] , xaxis = [1,0,0] , base = [0,0,0] , height = 5 , radius = 3; var srf = new verb.geom.ConicalSurface( axis, xaxis, base, height, radius ); should.exist(srf); var p = srf.point(0.5,0.5); p[0].should.be.approximately(-1.5, verb.core.Constants.EPSILON ); p[1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[2].should.be.approximately(2.5, verb.core.Constants.EPSILON ); }); }); describe("verb.geom.ConicalSurface.derivatives",function(){ it('gives expected result for middle of surface', function(){ var axis = [0,0,1] , xaxis = [1,0,0] , base = [0,0,0] , height = 5 , radius = 3; var srf = new verb.geom.ConicalSurface( axis, xaxis, base, height, radius ); should.exist(srf); var p = srf.derivatives(0.5, 0.5, 1); p[0][0][0].should.be.approximately(-1.5, verb.core.Constants.EPSILON ); p[0][0][1].should.be.approximately(0, verb.core.Constants.EPSILON ); p[0][0][2].should.be.approximately(2.5, verb.core.Constants.EPSILON ); p[0][1][0].should.be.approximately(-3, verb.core.C