@kitware/vtk.js 35.1.0 → 35.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -90,6 +90,34 @@ export function newInstance(initialValues?: ISphereInitialValues): vtkSphere;
90
90
  */
91
91
  declare function evaluate(radius: number, center: Vector3, x: Vector3): number;
92
92
 
93
+ /**
94
+ * Approximate bounding sphere for a point set represented as a flat xyz array.
95
+ * Returns `[cx, cy, cz, r]`.
96
+ *
97
+ * @param {Array<number>|TypedArray} pts flat xyz point coordinates
98
+ * @param {number} [numPts] number of points to process
99
+ * @param {number[]} [hints] two point ids expected to be far apart
100
+ */
101
+ declare function computeBoundingSphere(
102
+ pts: Array<number> | ArrayLike<number>,
103
+ numPts?: number,
104
+ hints?: number[]
105
+ ): [number, number, number, number];
106
+
107
+ /**
108
+ * Approximate bounding sphere for an array of spheres `[x, y, z, r]`.
109
+ * Returns `[cx, cy, cz, r]`.
110
+ *
111
+ * @param {Array<Vector4>} spheres list of spheres
112
+ * @param {number} [numSpheres] number of spheres to process
113
+ * @param {number[]} [hints] two sphere ids expected to be far apart
114
+ */
115
+ declare function computeBoundingSphereFromSpheres(
116
+ spheres: Array<[number, number, number, number]>,
117
+ numSpheres?: number,
118
+ hints?: number[]
119
+ ): [number, number, number, number];
120
+
93
121
  /**
94
122
  * vtkSphere provides methods for creating a 1D cubic spline object from given
95
123
  * parameters, and allows for the calculation of the spline value and derivative
@@ -99,5 +127,7 @@ export declare const vtkSphere: {
99
127
  newInstance: typeof newInstance;
100
128
  extend: typeof extend;
101
129
  evaluate: typeof evaluate;
130
+ computeBoundingSphere: typeof computeBoundingSphere;
131
+ computeBoundingSphereFromSpheres: typeof computeBoundingSphereFromSpheres;
102
132
  };
103
133
  export default vtkSphere;
@@ -1,5 +1,6 @@
1
1
  import { m as macro } from '../../macros2.js';
2
2
  import vtkImplicitFunction from './ImplicitFunction.js';
3
+ import { f as distance2BetweenPoints } from '../Core/Math/index.js';
3
4
 
4
5
  // ----------------------------------------------------------------------------
5
6
  // Global methods
@@ -13,13 +14,200 @@ function evaluate(radius, center, xyz) {
13
14
  const r = [(xyz[0] - center[0]) / radius[0], (xyz[1] - center[1]) / radius[1], (xyz[2] - center[2]) / radius[2]];
14
15
  return r[0] * r[0] + r[1] * r[1] + r[2] * r[2] - 1;
15
16
  }
17
+ function setPointFromArray(dst, pts, pointId) {
18
+ const offset = 3 * pointId;
19
+ dst[0] = pts[offset];
20
+ dst[1] = pts[offset + 1];
21
+ dst[2] = pts[offset + 2];
22
+ }
23
+ function copyPoint(dst, src) {
24
+ dst[0] = src[0];
25
+ dst[1] = src[1];
26
+ dst[2] = src[2];
27
+ }
28
+ function copySphere(dst, src) {
29
+ dst[0] = src[0];
30
+ dst[1] = src[1];
31
+ dst[2] = src[2];
32
+ dst[3] = src[3];
33
+ }
34
+
35
+ // Inspired by Graphics Gems Vol. I ("An Efficient Bounding Sphere" by Jack Ritter).
36
+ function computeBoundingSphere(pts, numPts, hints) {
37
+ const actualNumPts = numPts ?? Math.floor(pts.length / 3);
38
+ const sphere = [0, 0, 0, 0];
39
+ if (actualNumPts < 1) {
40
+ return sphere;
41
+ }
42
+ const d1 = [0, 0, 0];
43
+ const d2 = [0, 0, 0];
44
+ if (hints && hints.length >= 2) {
45
+ setPointFromArray(d1, pts, hints[0]);
46
+ setPointFromArray(d2, pts, hints[1]);
47
+ } else {
48
+ const xMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
49
+ const yMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
50
+ const zMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
51
+ const xMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
52
+ const yMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
53
+ const zMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
54
+ const p = [0, 0, 0];
55
+ for (let i = 0; i < actualNumPts; i++) {
56
+ setPointFromArray(p, pts, i);
57
+ if (p[0] < xMin[0]) copyPoint(xMin, p);
58
+ if (p[0] > xMax[0]) copyPoint(xMax, p);
59
+ if (p[1] < yMin[1]) copyPoint(yMin, p);
60
+ if (p[1] > yMax[1]) copyPoint(yMax, p);
61
+ if (p[2] < zMin[2]) copyPoint(zMin, p);
62
+ if (p[2] > zMax[2]) copyPoint(zMax, p);
63
+ }
64
+ const xSpan = distance2BetweenPoints(xMax, xMin);
65
+ const ySpan = distance2BetweenPoints(yMax, yMin);
66
+ const zSpan = distance2BetweenPoints(zMax, zMin);
67
+ if (xSpan > ySpan) {
68
+ if (xSpan > zSpan) {
69
+ copyPoint(d1, xMin);
70
+ copyPoint(d2, xMax);
71
+ } else {
72
+ copyPoint(d1, zMin);
73
+ copyPoint(d2, zMax);
74
+ }
75
+ } else if (ySpan > zSpan) {
76
+ copyPoint(d1, yMin);
77
+ copyPoint(d2, yMax);
78
+ } else {
79
+ copyPoint(d1, zMin);
80
+ copyPoint(d2, zMax);
81
+ }
82
+ }
83
+ sphere[0] = (d1[0] + d2[0]) / 2;
84
+ sphere[1] = (d1[1] + d2[1]) / 2;
85
+ sphere[2] = (d1[2] + d2[2]) / 2;
86
+ let r2 = distance2BetweenPoints(d1, d2) / 4;
87
+ sphere[3] = Math.sqrt(r2);
88
+ const p = [0, 0, 0];
89
+ for (let i = 0; i < actualNumPts; i++) {
90
+ setPointFromArray(p, pts, i);
91
+ const dist2 = distance2BetweenPoints(p, sphere);
92
+ if (dist2 > r2) {
93
+ const dist = Math.sqrt(dist2);
94
+ sphere[3] = (sphere[3] + dist) / 2;
95
+ r2 = sphere[3] * sphere[3];
96
+ const delta = dist - sphere[3];
97
+ sphere[0] = (sphere[3] * sphere[0] + delta * p[0]) / dist;
98
+ sphere[1] = (sphere[3] * sphere[1] + delta * p[1]) / dist;
99
+ sphere[2] = (sphere[3] * sphere[2] + delta * p[2]) / dist;
100
+ }
101
+ }
102
+ return sphere;
103
+ }
104
+ function computeBoundingSphereFromSpheres(spheres, numSpheres, hints) {
105
+ const actualNumSpheres = numSpheres ?? spheres.length;
106
+ const sphere = [0, 0, 0, 0];
107
+ if (actualNumSpheres < 1) {
108
+ return sphere;
109
+ }
110
+ if (actualNumSpheres === 1) {
111
+ copySphere(sphere, spheres[0]);
112
+ return sphere;
113
+ }
114
+ const s1 = [0, 0, 0, 0];
115
+ const s2 = [0, 0, 0, 0];
116
+ if (hints && hints.length >= 2) {
117
+ copySphere(s1, spheres[hints[0]]);
118
+ copySphere(s2, spheres[hints[1]]);
119
+ } else {
120
+ const xMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, 0];
121
+ const yMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, 0];
122
+ const zMin = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, 0];
123
+ const xMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, 0];
124
+ const yMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, 0];
125
+ const zMax = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, 0];
126
+ for (let i = 0; i < actualNumSpheres; i++) {
127
+ const s = spheres[i];
128
+ if (s[0] - s[3] < xMin[0] - xMin[3]) copySphere(xMin, s);
129
+ if (s[0] + s[3] > xMax[0] + xMax[3]) copySphere(xMax, s);
130
+ if (s[1] - s[3] < yMin[1] - yMin[3]) copySphere(yMin, s);
131
+ if (s[1] + s[3] > yMax[1] + yMax[3]) copySphere(yMax, s);
132
+ if (s[2] - s[3] < zMin[2] - zMin[3]) copySphere(zMin, s);
133
+ if (s[2] + s[3] > zMax[2] + zMax[3]) copySphere(zMax, s);
134
+ }
135
+ const xSpan = (xMax[0] + xMax[3] - (xMin[0] - xMin[3])) * (xMax[0] + xMax[3] - (xMin[0] - xMin[3])) + (xMax[1] + xMax[3] - (xMin[1] - xMin[3])) * (xMax[1] + xMax[3] - (xMin[1] - xMin[3])) + (xMax[2] + xMax[3] - (xMin[2] - xMin[3])) * (xMax[2] + xMax[3] - (xMin[2] - xMin[3]));
136
+ const ySpan = (yMax[0] + yMax[3] - (yMin[0] - yMin[3])) * (yMax[0] + yMax[3] - (yMin[0] - yMin[3])) + (yMax[1] + yMax[3] - (yMin[1] - yMin[3])) * (yMax[1] + yMax[3] - (yMin[1] - yMin[3])) + (yMax[2] + yMax[3] - (yMin[2] - yMin[3])) * (yMax[2] + yMax[3] - (yMin[2] - yMin[3]));
137
+ const zSpan = (zMax[0] + zMax[3] - (zMin[0] - zMin[3])) * (zMax[0] + zMax[3] - (zMin[0] - zMin[3])) + (zMax[1] + zMax[3] - (zMin[1] - zMin[3])) * (zMax[1] + zMax[3] - (zMin[1] - zMin[3])) + (zMax[2] + zMax[3] - (zMin[2] - zMin[3])) * (zMax[2] + zMax[3] - (zMin[2] - zMin[3]));
138
+ if (xSpan > ySpan) {
139
+ if (xSpan > zSpan) {
140
+ copySphere(s1, xMin);
141
+ copySphere(s2, xMax);
142
+ } else {
143
+ copySphere(s1, zMin);
144
+ copySphere(s2, zMax);
145
+ }
146
+ } else if (ySpan > zSpan) {
147
+ copySphere(s1, yMin);
148
+ copySphere(s2, yMax);
149
+ } else {
150
+ copySphere(s1, zMin);
151
+ copySphere(s2, zMax);
152
+ }
153
+ }
154
+ let r2 = distance2BetweenPoints(s1, s2) / 4;
155
+ sphere[3] = r2 > 0 ? Math.sqrt(r2) : s1[3];
156
+ const t1 = -s1[3] / (2 * sphere[3]);
157
+ const t2 = 1 + s2[3] / (2 * sphere[3]);
158
+ const v = [0, 0, 0];
159
+ for (let i = 0; i < 3; i++) {
160
+ v[i] = s2[i] - s1[i];
161
+ const tmp = s1[i] + t1 * v[i];
162
+ s2[i] = s1[i] + t2 * v[i];
163
+ s1[i] = tmp;
164
+ sphere[i] = (s1[i] + s2[i]) / 2;
165
+ }
166
+ r2 = distance2BetweenPoints(s1, s2) / 4;
167
+ if (r2 > 0) {
168
+ sphere[3] = Math.sqrt(r2);
169
+ } else {
170
+ sphere[3] = s1[3];
171
+ r2 = sphere[3] * sphere[3];
172
+ }
173
+ for (let i = 0; i < actualNumSpheres; i++) {
174
+ const s = spheres[i];
175
+ const sR2 = s[3] * s[3];
176
+ let dist2 = distance2BetweenPoints(s, sphere);
177
+ if (dist2 <= 0) {
178
+ dist2 = s[3];
179
+ }
180
+ const fac = sR2 > dist2 ? 2 * sR2 : 2 * dist2;
181
+ if (dist2 + fac + sR2 > r2) {
182
+ const dist = Math.sqrt(dist2);
183
+ if ((dist + s[3]) * (dist + s[3]) > r2) {
184
+ for (let j = 0; j < 3; j++) {
185
+ v[j] = s[j] - sphere[j];
186
+ s1[j] = sphere[j] - sphere[3] / dist * v[j];
187
+ s2[j] = sphere[j] + (1 + s[3] / dist) * v[j];
188
+ sphere[j] = (s1[j] + s2[j]) / 2;
189
+ }
190
+ r2 = distance2BetweenPoints(s1, s2) / 4;
191
+ if (r2 > 0) {
192
+ sphere[3] = Math.sqrt(r2);
193
+ } else {
194
+ sphere[3] = Math.max(s1[3], sphere[3]);
195
+ r2 = sphere[3] * sphere[3];
196
+ }
197
+ }
198
+ }
199
+ }
200
+ return sphere;
201
+ }
16
202
 
17
203
  // ----------------------------------------------------------------------------
18
204
  // Static API
19
205
  // ----------------------------------------------------------------------------
20
206
 
21
207
  const STATIC = {
22
- evaluate
208
+ evaluate,
209
+ computeBoundingSphere,
210
+ computeBoundingSphereFromSpheres
23
211
  };
24
212
 
25
213
  // ----------------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitware/vtk.js",
3
- "version": "35.1.0",
3
+ "version": "35.2.0",
4
4
  "description": "Visualization Toolkit for the Web",
5
5
  "keywords": [
6
6
  "3d",