@cornerstonejs/tools 3.15.5 → 3.16.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.
- package/dist/esm/drawingSvg/drawFan.d.ts +4 -0
- package/dist/esm/drawingSvg/drawFan.js +62 -0
- package/dist/esm/drawingSvg/drawLine.js +2 -1
- package/dist/esm/drawingSvg/index.d.ts +2 -1
- package/dist/esm/drawingSvg/index.js +2 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/tools/annotation/EllipticalROITool.js +17 -14
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.d.ts +64 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/UltrasoundPleuraBLineTool.js +752 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/calculateFanShapeCorners.d.ts +8 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/calculateFanShapeCorners.js +143 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/deriveFanGeometry.d.ts +2 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/deriveFanGeometry.js +32 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/fanExtraction.d.ts +7 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/fanExtraction.js +171 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/generateConvexHullFromContour.d.ts +5 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/generateConvexHullFromContour.js +6 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/segmentLargestUSOutlineFromBuffer.d.ts +2 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/segmentLargestUSOutlineFromBuffer.js +123 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/types.d.ts +41 -0
- package/dist/esm/tools/annotation/UltrasoundPleuraBLineTool/utils/types.js +0 -0
- package/dist/esm/tools/index.d.ts +2 -1
- package/dist/esm/tools/index.js +2 -1
- package/dist/esm/types/ToolSpecificAnnotationTypes.d.ts +10 -0
- package/dist/esm/utilities/index.d.ts +2 -1
- package/dist/esm/utilities/index.js +2 -1
- package/dist/esm/utilities/math/fan/fanUtils.d.ts +10 -0
- package/dist/esm/utilities/math/fan/fanUtils.js +99 -0
- package/dist/esm/utilities/math/line/intersectLine.d.ts +1 -1
- package/dist/esm/utilities/math/line/intersectLine.js +16 -6
- package/dist/esm/utilities/math/polyline/convexHull.d.ts +2 -0
- package/dist/esm/utilities/math/polyline/convexHull.js +31 -0
- package/dist/esm/utilities/math/polyline/index.d.ts +2 -1
- package/dist/esm/utilities/math/polyline/index.js +2 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
function normalizeAngle(angle) {
|
|
2
|
+
return ((angle % 360) + 360) % 360;
|
|
3
|
+
}
|
|
4
|
+
export function angleFromCenter(center, point) {
|
|
5
|
+
const dx = point[0] - center[0];
|
|
6
|
+
const dy = point[1] - center[1];
|
|
7
|
+
const angle = Math.atan2(dy, dx) * (180 / Math.PI);
|
|
8
|
+
return normalizeAngle(angle);
|
|
9
|
+
}
|
|
10
|
+
export function intervalFromPoints(center, pair) {
|
|
11
|
+
const start = angleFromCenter(center, pair[0]);
|
|
12
|
+
const end = angleFromCenter(center, pair[1]);
|
|
13
|
+
return start < end ? [start, end] : [end, start];
|
|
14
|
+
}
|
|
15
|
+
export function mergeIntervals(intervals) {
|
|
16
|
+
if (!intervals.length) {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
intervals.sort((a, b) => a[0] - b[0]);
|
|
20
|
+
const merged = [intervals[0].slice()];
|
|
21
|
+
for (let i = 1; i < intervals.length; i++) {
|
|
22
|
+
const last = merged[merged.length - 1];
|
|
23
|
+
const current = intervals[i];
|
|
24
|
+
if (current[0] <= last[1]) {
|
|
25
|
+
last[1] = Math.max(last[1], current[1]);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
merged.push(current.slice());
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return merged;
|
|
32
|
+
}
|
|
33
|
+
export function subtractIntervals(blocked, target) {
|
|
34
|
+
const [T0, T1] = target;
|
|
35
|
+
if (T1 <= T0) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
const overlaps = blocked
|
|
39
|
+
.map(([a, b]) => [Math.max(a, T0), Math.min(b, T1)])
|
|
40
|
+
.filter(([a, b]) => b > a);
|
|
41
|
+
if (overlaps.length === 0) {
|
|
42
|
+
return [[T0, T1]];
|
|
43
|
+
}
|
|
44
|
+
overlaps.sort((p, q) => p[0] - q[0]);
|
|
45
|
+
const merged = [];
|
|
46
|
+
let [curA, curB] = overlaps[0];
|
|
47
|
+
for (let i = 1; i < overlaps.length; i++) {
|
|
48
|
+
const [a, b] = overlaps[i];
|
|
49
|
+
if (a <= curB) {
|
|
50
|
+
curB = Math.max(curB, b);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
merged.push([curA, curB]);
|
|
54
|
+
[curA, curB] = [a, b];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
merged.push([curA, curB]);
|
|
58
|
+
const gaps = [];
|
|
59
|
+
let cursor = T0;
|
|
60
|
+
for (const [a, b] of merged) {
|
|
61
|
+
if (a > cursor) {
|
|
62
|
+
gaps.push([cursor, a]);
|
|
63
|
+
}
|
|
64
|
+
cursor = Math.max(cursor, b);
|
|
65
|
+
}
|
|
66
|
+
if (cursor < T1) {
|
|
67
|
+
gaps.push([cursor, T1]);
|
|
68
|
+
}
|
|
69
|
+
return gaps;
|
|
70
|
+
}
|
|
71
|
+
export function clipInterval(inner, outerMerged) {
|
|
72
|
+
const result = [];
|
|
73
|
+
for (const out of outerMerged) {
|
|
74
|
+
const start = Math.max(inner[0], out[0]);
|
|
75
|
+
const end = Math.min(inner[1], out[1]);
|
|
76
|
+
if (start < end) {
|
|
77
|
+
result.push([start, end]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
export function calculateInnerFanPercentage(center, outerFanPairs, innerFanPairs) {
|
|
83
|
+
const outerIntervals = outerFanPairs.map((pair) => intervalFromPoints(center, pair));
|
|
84
|
+
const mergedOuter = mergeIntervals(outerIntervals);
|
|
85
|
+
const outerTotal = mergedOuter.reduce((sum, [a, b]) => sum + (b - a), 0);
|
|
86
|
+
if (outerTotal === 0) {
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
const clippedInnerIntervals = [];
|
|
90
|
+
for (const pair of innerFanPairs) {
|
|
91
|
+
const innerInterval = intervalFromPoints(center, pair);
|
|
92
|
+
const clipped = clipInterval(innerInterval, mergedOuter);
|
|
93
|
+
clippedInnerIntervals.push(...clipped);
|
|
94
|
+
}
|
|
95
|
+
const mergedInner = mergeIntervals(clippedInnerIntervals);
|
|
96
|
+
const innerTotal = mergedInner.reduce((sum, [a, b]) => sum + (b - a), 0);
|
|
97
|
+
const percentage = (innerTotal / outerTotal) * 100;
|
|
98
|
+
return Math.min(100, Math.max(0, percentage));
|
|
99
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Types } from '@cornerstonejs/core';
|
|
2
|
-
export default function intersectLine(line1Start: Types.Point2, line1End: Types.Point2, line2Start: Types.Point2, line2End: Types.Point2): number[];
|
|
2
|
+
export default function intersectLine(line1Start: Types.Point2, line1End: Types.Point2, line2Start: Types.Point2, line2End: Types.Point2, infinite?: boolean): number[] | undefined;
|
|
@@ -9,18 +9,28 @@ function sign(x) {
|
|
|
9
9
|
: NaN
|
|
10
10
|
: NaN;
|
|
11
11
|
}
|
|
12
|
-
export default function intersectLine(line1Start, line1End, line2Start, line2End) {
|
|
12
|
+
export default function intersectLine(line1Start, line1End, line2Start, line2End, infinite = false) {
|
|
13
13
|
const [x1, y1] = line1Start;
|
|
14
14
|
const [x2, y2] = line1End;
|
|
15
15
|
const [x3, y3] = line2Start;
|
|
16
16
|
const [x4, y4] = line2End;
|
|
17
|
+
if (infinite) {
|
|
18
|
+
const denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
|
|
19
|
+
if (Math.abs(denom) < 1e-10) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom;
|
|
23
|
+
const x = x1 + t * (x2 - x1);
|
|
24
|
+
const y = y1 + t * (y2 - y1);
|
|
25
|
+
return [x, y];
|
|
26
|
+
}
|
|
17
27
|
const a1 = y2 - y1;
|
|
18
28
|
const b1 = x1 - x2;
|
|
19
29
|
const c1 = x2 * y1 - x1 * y2;
|
|
20
30
|
const r3 = a1 * x3 + b1 * y3 + c1;
|
|
21
31
|
const r4 = a1 * x4 + b1 * y4 + c1;
|
|
22
32
|
if (r3 !== 0 && r4 !== 0 && sign(r3) === sign(r4)) {
|
|
23
|
-
return;
|
|
33
|
+
return undefined;
|
|
24
34
|
}
|
|
25
35
|
const a2 = y4 - y3;
|
|
26
36
|
const b2 = x3 - x4;
|
|
@@ -28,14 +38,14 @@ export default function intersectLine(line1Start, line1End, line2Start, line2End
|
|
|
28
38
|
const r1 = a2 * x1 + b2 * y1 + c2;
|
|
29
39
|
const r2 = a2 * x2 + b2 * y2 + c2;
|
|
30
40
|
if (r1 !== 0 && r2 !== 0 && sign(r1) === sign(r2)) {
|
|
31
|
-
return;
|
|
41
|
+
return undefined;
|
|
32
42
|
}
|
|
33
|
-
const
|
|
43
|
+
const denomSegment = a1 * b2 - a2 * b1;
|
|
34
44
|
let num;
|
|
35
45
|
num = b1 * c2 - b2 * c1;
|
|
36
|
-
const x = num /
|
|
46
|
+
const x = num / denomSegment;
|
|
37
47
|
num = a2 * c1 - a1 * c2;
|
|
38
|
-
const y = num /
|
|
48
|
+
const y = num / denomSegment;
|
|
39
49
|
const intersectionPoint = [x, y];
|
|
40
50
|
return intersectionPoint;
|
|
41
51
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export default function convexHull(pts) {
|
|
2
|
+
if (pts.length < 3) {
|
|
3
|
+
return pts.slice();
|
|
4
|
+
}
|
|
5
|
+
const points = pts
|
|
6
|
+
.map((p) => [p[0], p[1]])
|
|
7
|
+
.sort((a, b) => a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
|
|
8
|
+
function cross(o, a, b) {
|
|
9
|
+
return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
|
|
10
|
+
}
|
|
11
|
+
const lower = [];
|
|
12
|
+
for (const p of points) {
|
|
13
|
+
while (lower.length >= 2 &&
|
|
14
|
+
cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {
|
|
15
|
+
lower.pop();
|
|
16
|
+
}
|
|
17
|
+
lower.push(p);
|
|
18
|
+
}
|
|
19
|
+
const upper = [];
|
|
20
|
+
for (let i = points.length - 1; i >= 0; i--) {
|
|
21
|
+
const p = points[i];
|
|
22
|
+
while (upper.length >= 2 &&
|
|
23
|
+
cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {
|
|
24
|
+
upper.pop();
|
|
25
|
+
}
|
|
26
|
+
upper.push(p);
|
|
27
|
+
}
|
|
28
|
+
lower.pop();
|
|
29
|
+
upper.pop();
|
|
30
|
+
return lower.concat(upper);
|
|
31
|
+
}
|
|
@@ -20,4 +20,5 @@ import addCanvasPointsToArray from './addCanvasPointsToArray';
|
|
|
20
20
|
import pointCanProjectOnLine from './pointCanProjectOnLine';
|
|
21
21
|
import { isPointInsidePolyline3D } from './isPointInsidePolyline3D';
|
|
22
22
|
import { projectTo2D } from './projectTo2D';
|
|
23
|
-
|
|
23
|
+
import convexHull from './convexHull';
|
|
24
|
+
export { isClosed, containsPoint, containsPoints, getAABB, getArea, getSignedArea, getWindingDirection, getNormal3, getNormal2, intersectPolyline, decimate, getFirstLineSegmentIntersectionIndexes, getLineSegmentIntersectionsIndexes, getLineSegmentIntersectionsCoordinates, getClosestLineSegmentIntersection, getSubPixelSpacingAndXYDirections, pointsAreWithinCloseContourProximity, addCanvasPointsToArray, pointCanProjectOnLine, mergePolylines, subtractPolylines, isPointInsidePolyline3D, projectTo2D, convexHull, };
|
|
@@ -20,4 +20,5 @@ import addCanvasPointsToArray from './addCanvasPointsToArray';
|
|
|
20
20
|
import pointCanProjectOnLine from './pointCanProjectOnLine';
|
|
21
21
|
import { isPointInsidePolyline3D } from './isPointInsidePolyline3D';
|
|
22
22
|
import { projectTo2D } from './projectTo2D';
|
|
23
|
-
|
|
23
|
+
import convexHull from './convexHull';
|
|
24
|
+
export { isClosed, containsPoint, containsPoints, getAABB, getArea, getSignedArea, getWindingDirection, getNormal3, getNormal2, intersectPolyline, decimate, getFirstLineSegmentIntersectionIndexes, getLineSegmentIntersectionsIndexes, getLineSegmentIntersectionsCoordinates, getClosestLineSegmentIntersection, getSubPixelSpacingAndXYDirections, pointsAreWithinCloseContourProximity, addCanvasPointsToArray, pointCanProjectOnLine, mergePolylines, subtractPolylines, isPointInsidePolyline3D, projectTo2D, convexHull, };
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "3.
|
|
1
|
+
export declare const version = "3.16.0";
|
package/dist/esm/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '3.
|
|
1
|
+
export const version = '3.16.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
4
4
|
"description": "Cornerstone3D Tools",
|
|
5
5
|
"types": "./dist/esm/index.d.ts",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"canvas": "^3.1.0"
|
|
109
109
|
},
|
|
110
110
|
"peerDependencies": {
|
|
111
|
-
"@cornerstonejs/core": "^3.
|
|
111
|
+
"@cornerstonejs/core": "^3.16.0",
|
|
112
112
|
"@kitware/vtk.js": "32.12.1",
|
|
113
113
|
"@types/d3-array": "^3.0.4",
|
|
114
114
|
"@types/d3-interpolate": "^3.0.1",
|
|
@@ -127,5 +127,5 @@
|
|
|
127
127
|
"type": "individual",
|
|
128
128
|
"url": "https://ohif.org/donate"
|
|
129
129
|
},
|
|
130
|
-
"gitHead": "
|
|
130
|
+
"gitHead": "16136620b12d12a19fe62f8b8a2ddbc468c4543b"
|
|
131
131
|
}
|