diff --git a/index.js b/index.js index 923189b..56cef6e 100644 --- a/index.js +++ b/index.js @@ -285,8 +285,21 @@ } return new_rs; - } + }, + + // Arvo's algorithm + // Arvo, James, A Simple Method for Box-Sphere Intersection Testing, p. 335-339, code: p. 730-732, BoxSphere.c. + // solid-solid case + // `sphere` should be Array [ x, y, z, radius ] + intersectWithSphere: function( sphere ) { + var dmin = 0; + for ( var i = 0; i < this._numDimensions; i++ ) { + if ( sphere[i] < this.min[i] ) dmin += Math.pow( ( sphere[i] - this.min[i] ), 2 ); + if ( sphere[i] > this.max[i] ) dmin += Math.pow( ( sphere[i] - this.max[i] ), 2 ); + } + return dmin <= Math.pow( sphere[ this._numDimensions ], 2 ) + } }; return AABB; -})); \ No newline at end of file +})); diff --git a/test/aabb-test.js b/test/aabb-test.js index 0135f4e..252265f 100644 --- a/test/aabb-test.js +++ b/test/aabb-test.js @@ -43,6 +43,14 @@ vows.describe('AABB').addBatch({ var t = new AABB([-6, -3], [6, 2]) assert.isFalse (aabb.contained(t)); }, + 'circle intersects': function( aabb ) { + var c = [ 0, 0, 1 ]; + assert.isTrue( aabb.intersectWithSphere( c ) ); + }, + 'circle does not intersect': function( aabb ) { + var c = [ 10, 10, 1 ]; + assert.isFalse( aabb.intersectWithSphere( c ) ); + } }, 'Testing 3D AABB': { topic: function(){ return new AABB([-5, -2, -5], [5, 3, 5]); }, @@ -104,6 +112,14 @@ vows.describe('AABB').addBatch({ {a: 0, b: 0} ]; assert.isFalse (aabb.intersectWithSegment(s)); - } + }, + 'sphere intersects': function( aabb ) { + var s = [ 0, 0, 0, 1 ]; + assert.isTrue( aabb.intersectWithSphere( s ) ); + }, + 'sphere does not intersect': function( aabb ) { + var s = [ 10, 10, 10, 1 ]; + assert.isFalse( aabb.intersectWithSphere( s ) ); + } } }).export(module);