k-l-lambda's picture
feat: add Python ML services (CPU mode) with model download
2b7aae2
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 {
constructor(center = new Vector3(), radius = -1) {
this.center = center;
this.radius = radius;
}
set(center, radius) {
this.center.copy(center);
this.radius = radius;
return this;
}
setFromPoints(points, optionalCenter) {
const center = this.center;
if (optionalCenter !== undefined) {
center.copy(optionalCenter);
} else {
_box.setFromPoints(points).getCenter(center);
}
let maxRadiusSq = 0;
for (let i = 0, il = points.length; i < il; i++) {
maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i]));
}
this.radius = Math.sqrt(maxRadiusSq);
return this;
}
copy(sphere) {
this.center.copy(sphere.center);
this.radius = sphere.radius;
return this;
}
isEmpty() {
return this.radius < 0;
}
makeEmpty() {
this.center.set(0, 0, 0);
this.radius = -1;
return this;
}
containsPoint(point) {
return point.distanceToSquared(this.center) <= this.radius * this.radius;
}
distanceToPoint(point) {
return point.distanceTo(this.center) - this.radius;
}
intersectsSphere(sphere) {
const radiusSum = this.radius + sphere.radius;
return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum;
}
intersectsBox(box) {
return box.intersectsSphere(this);
}
intersectsPlane(plane) {
return Math.abs(plane.distanceToPoint(this.center)) <= this.radius;
}
clampPoint(point, target) {
const deltaLengthSq = this.center.distanceToSquared(point);
target.copy(point);
if (deltaLengthSq > this.radius * this.radius) {
target.sub(this.center).normalize();
target.multiplyScalar(this.radius).add(this.center);
}
return target;
}
getBoundingBox(target) {
if (this.isEmpty()) {
// Empty sphere produces empty bounding box
target.makeEmpty();
return target;
}
target.set(this.center, this.center);
target.expandByScalar(this.radius);
return target;
}
applyMatrix4(matrix) {
this.center.applyMatrix4(matrix);
this.radius = this.radius * matrix.getMaxScaleOnAxis();
return this;
}
translate(offset) {
this.center.add(offset);
return this;
}
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.
if (this.center.equals(sphere.center) === true) {
_toFarthestPoint.set(0, 0, 1).multiplyScalar(sphere.radius);
} else {
_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;
}
clone() {
return new this.constructor().copy(this);
}
}
export { Sphere };