Skip to content

Commit

Permalink
Sphere: Add expandByPoint() and union(). (#21493)
Browse files Browse the repository at this point in the history
* Sphere: Add expandByPoint() and union().

* Tests: Clean up.
  • Loading branch information
Mugen87 committed Mar 23, 2021
1 parent 19bb1ae commit 95ce8f1
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 71 deletions.
14 changes: 14 additions & 0 deletions docs/api/en/math/Sphere.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ <h3>[method:Float distanceToPoint]( [param:Vector3 point] )</h3>
the distance will be negative.
</p>

<h3>[method:this expandByPoint]( [param:Vector3 point] )</h3>
<p>
[page:Vector3 point] - [page:Vector3] that should be included in the sphere.<br /><br />

Expands the boundaries of this sphere to include [page:Vector3 point].
</p>

<h3>[method:Boolean isEmpty]()</h3>
<p>
Checks to see if the sphere is empty (the radius set to a negative number).</br>
Expand Down Expand Up @@ -138,6 +145,13 @@ <h3>[method:Sphere translate]( [param:Vector3 offset] )</h3>
Translate the sphere's center by the provided offset [page:Vector3].
</p>

<h3>[method:this union]( [param:Sphere sphere] )</h3>
<p>
[page:Sphere sphere] - Bounding sphere that will be unioned with this sphere.<br /><br />

Expands this sphere to enclose both the original sphere and the given sphere.
</p>

<h2>Source</h2>

<p>
Expand Down
14 changes: 14 additions & 0 deletions docs/api/zh/math/Sphere.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ <h3>[method:Float distanceToPoint]( [param:Vector3 point] )</h3>
若这个点,则距离将为负值。
</p>

<h3>[method:this expandByPoint]( [param:Vector3 point] )</h3>
<p>
[page:Vector3 point] - [page:Vector3] that should be included in the sphere.<br /><br />

Expands the boundaries of this sphere to include [page:Vector3 point].
</p>

<h3>[method:Boolean isEmpty]()</h3>
<p>
检查球是否为空(the radius set to a negative number).
Expand Down Expand Up @@ -134,6 +141,13 @@ <h3>[method:Sphere translate]( [param:Vector3 offset] )</h3>
使用所给定[page:Vector3] offset(偏移量)平移球心。
</p>

<h3>[method:this union]( [param:Sphere sphere] )</h3>
<p>
[page:Sphere sphere] - Bounding sphere that will be unioned with this sphere.<br /><br />

Expands this sphere to enclose both the original sphere and the given sphere.
</p>

<h2>源代码</h2>

<p>
Expand Down
46 changes: 46 additions & 0 deletions src/math/Sphere.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { Box3 } from './Box3.js';
import { Vector3 } from './Vector3.js';

const _box = /*@__PURE__*/ new Box3();
const _v1 = /*@__PURE__*/ new Vector3();
const _toFarthestPoint = /*@__PURE__*/ new Vector3();
const _toPoint = /*@__PURE__*/ new Vector3();

class Sphere {

Expand Down Expand Up @@ -170,6 +173,49 @@ class Sphere {

}

expandByPoint( point ) {

// from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671

_toPoint.subVectors( point, this.center );

const lengthSq = _toPoint.lengthSq();

if ( lengthSq > ( this.radius * this.radius ) ) {

const length = Math.sqrt( lengthSq );
const missingRadiusHalf = ( length - this.radius ) * 0.5;

// Nudge this sphere towards the target point. Add half the missing distance to radius,
// and the other half to position. This gives a tighter enclosure, instead of if
// the whole missing distance were just added to radius.

this.center.add( _toPoint.multiplyScalar( missingRadiusHalf / length ) );
this.radius += missingRadiusHalf;

}

return this;

}

union( sphere ) {

// from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769

// To enclose another sphere into this sphere, we only need to enclose two points:
// 1) Enclose the farthest point on the other sphere into this sphere.
// 2) Enclose the opposite point of the farthest point into this sphere.

_toFarthestPoint.subVectors( sphere.center, this.center ).normalize().multiplyScalar( sphere.radius );

this.expandByPoint( _v1.copy( sphere.center ).add( _toFarthestPoint ) );
this.expandByPoint( _v1.copy( sphere.center ).sub( _toFarthestPoint ) );

return this;

}

equals( sphere ) {

return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
Expand Down
Loading

0 comments on commit 95ce8f1

Please sign in to comment.