Skip to content

Commit

Permalink
Added new empty concept to sphere with a negative radius. Modified co…
Browse files Browse the repository at this point in the history
…ntainment / intersection functions to honor isEmpty and return false in this case
  • Loading branch information
samfoster committed Apr 2, 2020
1 parent c1ff1f1 commit 7548e1c
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 18 deletions.
12 changes: 8 additions & 4 deletions docs/api/en/math/Sphere.html
Expand Up @@ -11,12 +11,13 @@
<h1>[name]</h1>

<p class="desc">A sphere defined by a center and radius.</p>
<p></p>

<h2>Constructor</h2>
<h3>[name]( [param:Vector3 center], [param:Float radius] )</h3>
<p>
[page:Vector3 center] - center of the sphere. Default is a [page:Vector3] at (0, 0, 0). <br />
[page:Float radius] - radius of the sphere. Default is 0.<br /><br />
[page:Float radius] - radius of the sphere. Default is -1.<br /><br />

Creates a new [name].

Expand Down Expand Up @@ -73,11 +74,14 @@ <h3>[method:Float distanceToPoint]( [param:Vector3 point] )</h3>
the distance will be negative.
</p>

<h3>[method:Boolean empty]()</h3>
<p>Checks to see if the sphere is empty (the radius set to 0).</p>
<h3>[method:Boolean isEmpty]()</h3>
<p>
Checks to see if the sphere is empty (the radius set to a negative number).</br>
Spheres with a radius of 0 contain only their center point and are not considererd to be empty.
</p>

<h3>[method:Sphere makeEmpty]()</h3>
<p>Makes the sphere empty by setting [page:.center center] to (0, 0, 0) and [page:.radius radius] to 0.</p>
<p>Makes the sphere empty by setting [page:.center center] to (0, 0, 0) and [page:.radius radius] to -1.</p>

<h3>[method:Boolean equals]( [param:Sphere sphere] )</h3>
<p>
Expand Down
4 changes: 2 additions & 2 deletions docs/api/zh/math/Sphere.html
Expand Up @@ -70,8 +70,8 @@ <h3>[method:Float distanceToPoint]( [param:Vector3 point] )</h3>
若这个点,则距离将为负值。
</p>

<h3>[method:Boolean empty]()</h3>
<p>检查球是否为空(其半径设为了0).</p>
<h3>[method:Boolean isEmpty]()</h3>
<p>检查球是否为空(the radius set to a negative number).</p>

<h3>[method:Sphere makeEmpty]()</h3>
<p>Makes the sphere empty by setting [page:.center center] to (0, 0, 0) and [page:.radius radius] to 0.</p>
Expand Down
11 changes: 11 additions & 0 deletions src/Three.Legacy.js
Expand Up @@ -542,6 +542,17 @@ Object.assign( Box3.prototype, {
}
} );

Object.assign( Sphere.prototype, {

empty: function() {

console.warn( 'THREE.Sphere: .empty() has been renamed to .isEmpty().' );
return this.isEmpty();

},

} );

Frustum.prototype.setFromMatrix = function ( m ) {

console.warn( 'THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().' );
Expand Down
6 changes: 6 additions & 0 deletions src/math/Box3.js
Expand Up @@ -325,6 +325,12 @@ Object.assign( Box3.prototype, {

intersectsSphere: function ( sphere ) {

if( sphere.isEmpty() ) {

return false;

}

// Find the point on the AABB closest to the sphere center.
this.clampPoint( sphere.center, _vector );

Expand Down
7 changes: 6 additions & 1 deletion src/math/Sphere.d.ts
Expand Up @@ -14,7 +14,7 @@ export class Sphere {
setFromPoints( points: Vector3[], optionalCenter?: Vector3 ): Sphere;
clone(): this;
copy( sphere: Sphere ): this;
empty(): boolean;
isEmpty(): boolean;
makeEmpty(): this;
containsPoint( point: Vector3 ): boolean;
distanceToPoint( point: Vector3 ): number;
Expand All @@ -27,4 +27,9 @@ export class Sphere {
translate( offset: Vector3 ): Sphere;
equals( sphere: Sphere ): boolean;

/**
* @deprecated Use {@link Sphere#isEmpty .isEmpty()} instead.
*/
empty(): any;

}
27 changes: 23 additions & 4 deletions src/math/Sphere.js
Expand Up @@ -11,7 +11,7 @@ var _box = new Box3();
function Sphere( center, radius ) {

this.center = ( center !== undefined ) ? center : new Vector3();
this.radius = ( radius !== undefined ) ? radius : 0;
this.radius = ( radius !== undefined ) ? radius : -1;

}

Expand Down Expand Up @@ -69,23 +69,29 @@ Object.assign( Sphere.prototype, {

},

empty: function () {
isEmpty: function () {

return ( this.radius <= 0 );
return ( this.radius < 0 );

},

makeEmpty: function () {

this.center.set( 0, 0, 0 );
this.radius = 0;
this.radius = -1;

return this;

},

containsPoint: function ( point ) {

if( this.isEmpty() ) {

return false;

}

return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );

},
Expand All @@ -98,6 +104,12 @@ Object.assign( Sphere.prototype, {

intersectsSphere: function ( sphere ) {

if( this.isEmpty() ) {

return false;

}

var radiusSum = this.radius + sphere.radius;

return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
Expand Down Expand Up @@ -149,6 +161,13 @@ Object.assign( Sphere.prototype, {

}

if( this.isEmpty() ) {

target.makeEmpty();
return target;

}

target.set( this.center, this.center );
target.expandByScalar( this.radius );

Expand Down
44 changes: 37 additions & 7 deletions test/unit/src/math/Sphere.tests.js
Expand Up @@ -108,22 +108,32 @@ export default QUnit.module( 'Maths', () => {

} );

QUnit.test( "empty", ( assert ) => {
QUnit.test( "isEmpty", ( assert ) => {

var a = new Sphere();
assert.ok( a.empty(), "Passed!" );
assert.ok( a.isEmpty(), "Passed!" );

a.set( one3, 1 );
assert.ok( ! a.empty(), "Passed!" );
assert.ok( ! a.isEmpty(), "Passed!" );

// Negative radius contains no points
a.set( one3, -1 );
assert.ok( a.isEmpty(), "Passed!" );

// Zero radius contains only the center point
a.set( one3, 0 );
assert.ok( ! a.isEmpty(), "Passed!" );

} );

QUnit.test( "makeEmpty", ( assert ) => {

var a = new Sphere( one3.clone(), 1 );

assert.ok( ! a.isEmpty(), "Passed!" );

a.makeEmpty();
assert.ok( a.empty(), "Passed!" );
assert.ok( a.isEmpty(), "Passed!" );
assert.ok( a.center.equals( zero3 ), "Passed!" );

} );
Expand All @@ -135,6 +145,12 @@ export default QUnit.module( 'Maths', () => {
assert.ok( ! a.containsPoint( zero3 ), "Passed!" );
assert.ok( a.containsPoint( one3 ), "Passed!" );

a.set( zero3, 0 );
assert.ok( a.containsPoint( a.center ), "Passed!" );

a.makeEmpty();
assert.ok( !a.containsPoint( a.center ), "Passed" );

} );

QUnit.test( "distanceToPoint", ( assert ) => {
Expand All @@ -155,17 +171,23 @@ export default QUnit.module( 'Maths', () => {
assert.ok( a.intersectsSphere( b ), "Passed!" );
assert.ok( ! a.intersectsSphere( c ), "Passed!" );

a.makeEmpty();
assert.ok( !a.intersectsSphere( a ), "Passed!" );

} );

QUnit.test( "intersectsBox", ( assert ) => {

var a = new Sphere();
var b = new Sphere( new Vector3( - 5, - 5, - 5 ) );
var a = new Sphere( zero3, 1 );
var b = new Sphere( new Vector3( - 5, - 5, - 5 ), 1 );
var box = new Box3( zero3, one3 );

assert.strictEqual( a.intersectsBox( box ), true, "Check default sphere" );
assert.strictEqual( a.intersectsBox( box ), true, "Check unit sphere" );
assert.strictEqual( b.intersectsBox( box ), false, "Check shifted sphere" );

a.makeEmpty();
assert.strictEqual( a.intersectsBox( box ), false , "Check empty sphere");

} );

QUnit.test( "intersectsPlane", ( assert ) => {
Expand All @@ -179,6 +201,9 @@ export default QUnit.module( 'Maths', () => {
assert.ok( ! a.intersectsPlane( c ), "Passed!" );
assert.ok( ! a.intersectsPlane( d ), "Passed!" );

a.makeEmpty();
assert.ok( ! a.intersectsPlane( b ), "Passed!" );

} );

QUnit.test( "clampPoint", ( assert ) => {
Expand All @@ -205,6 +230,11 @@ export default QUnit.module( 'Maths', () => {
a.getBoundingBox( aabb );
assert.ok( aabb.equals( new Box3( zero3, zero3 ) ), "Passed!" );

// Empty sphere produces empty bounding box
a.makeEmpty();
a.getBoundingBox( aabb );
assert.ok( aabb.isEmpty(), "Passed!" );

} );

QUnit.test( "applyMatrix4", ( assert ) => {
Expand Down

0 comments on commit 7548e1c

Please sign in to comment.