@cornerstonejs/tools 1.58.1 → 1.58.2
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/cjs/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js +6 -1
- package/dist/cjs/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js.map +1 -1
- package/dist/cjs/types/ContourSegmentationAnnotation.d.ts +5 -0
- package/dist/cjs/types/IToolGroup.d.ts +3 -1
- package/dist/cjs/types/ToolSpecificAnnotationTypes.d.ts +2 -1
- package/dist/cjs/utilities/contours/interpolation/getInterpolationData.js +15 -2
- package/dist/cjs/utilities/contours/interpolation/getInterpolationData.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/interpolate.js +1 -4
- package/dist/cjs/utilities/contours/interpolation/interpolate.js.map +1 -1
- package/dist/cjs/utilities/contours/interpolation/selectHandles.js +2 -3
- package/dist/cjs/utilities/contours/interpolation/selectHandles.js.map +1 -1
- package/dist/cjs/utilities/math/line/index.d.ts +2 -1
- package/dist/cjs/utilities/math/line/index.js +3 -1
- package/dist/cjs/utilities/math/line/index.js.map +1 -1
- package/dist/cjs/utilities/math/line/isPointOnLineSegment.d.ts +2 -0
- package/dist/cjs/utilities/math/line/isPointOnLineSegment.js +22 -0
- package/dist/cjs/utilities/math/line/isPointOnLineSegment.js.map +1 -0
- package/dist/cjs/utilities/math/polyline/combinePolyline.js +2 -2
- package/dist/cjs/utilities/math/polyline/combinePolyline.js.map +1 -1
- package/dist/cjs/utilities/math/polyline/getLineSegmentIntersectionsCoordinates.js +2 -2
- package/dist/cjs/utilities/math/polyline/getLineSegmentIntersectionsCoordinates.js.map +1 -1
- package/dist/cjs/utilities/math/polyline/getLinesIntersection.d.ts +2 -0
- package/dist/cjs/utilities/math/polyline/getLinesIntersection.js +78 -0
- package/dist/cjs/utilities/math/polyline/getLinesIntersection.js.map +1 -0
- package/dist/cjs/utilities/segmentation/InterpolationManager/InterpolationManager.js +30 -12
- package/dist/cjs/utilities/segmentation/InterpolationManager/InterpolationManager.js.map +1 -1
- package/dist/esm/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js +6 -0
- package/dist/esm/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/getInterpolationData.js +15 -2
- package/dist/esm/utilities/contours/interpolation/getInterpolationData.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/interpolate.js +1 -4
- package/dist/esm/utilities/contours/interpolation/interpolate.js.map +1 -1
- package/dist/esm/utilities/contours/interpolation/selectHandles.js +2 -3
- package/dist/esm/utilities/contours/interpolation/selectHandles.js.map +1 -1
- package/dist/esm/utilities/math/line/index.js +2 -1
- package/dist/esm/utilities/math/line/index.js.map +1 -1
- package/dist/esm/utilities/math/line/isPointOnLineSegment.js +19 -0
- package/dist/esm/utilities/math/line/isPointOnLineSegment.js.map +1 -0
- package/dist/esm/utilities/math/polyline/combinePolyline.js +2 -2
- package/dist/esm/utilities/math/polyline/combinePolyline.js.map +1 -1
- package/dist/esm/utilities/math/polyline/getLineSegmentIntersectionsCoordinates.js +2 -2
- package/dist/esm/utilities/math/polyline/getLineSegmentIntersectionsCoordinates.js.map +1 -1
- package/dist/esm/utilities/math/polyline/getLinesIntersection.js +52 -0
- package/dist/esm/utilities/math/polyline/getLinesIntersection.js.map +1 -0
- package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js +30 -12
- package/dist/esm/utilities/segmentation/InterpolationManager/InterpolationManager.js.map +1 -1
- package/dist/types/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.d.ts.map +1 -1
- package/dist/types/types/ContourSegmentationAnnotation.d.ts +5 -0
- package/dist/types/types/ContourSegmentationAnnotation.d.ts.map +1 -1
- package/dist/types/types/IToolGroup.d.ts +3 -1
- package/dist/types/types/IToolGroup.d.ts.map +1 -1
- package/dist/types/types/ToolSpecificAnnotationTypes.d.ts +2 -1
- package/dist/types/types/ToolSpecificAnnotationTypes.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/getInterpolationData.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/interpolate.d.ts.map +1 -1
- package/dist/types/utilities/contours/interpolation/selectHandles.d.ts.map +1 -1
- package/dist/types/utilities/math/line/index.d.ts +2 -1
- package/dist/types/utilities/math/line/index.d.ts.map +1 -1
- package/dist/types/utilities/math/line/isPointOnLineSegment.d.ts +3 -0
- package/dist/types/utilities/math/line/isPointOnLineSegment.d.ts.map +1 -0
- package/dist/types/utilities/math/polyline/combinePolyline.d.ts.map +1 -1
- package/dist/types/utilities/math/polyline/getLinesIntersection.d.ts +3 -0
- package/dist/types/utilities/math/polyline/getLinesIntersection.d.ts.map +1 -0
- package/dist/types/utilities/segmentation/InterpolationManager/InterpolationManager.d.ts.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +3 -3
- package/src/eventListeners/annotations/contourSegmentation/contourSegmentationCompleted.ts +8 -0
- package/src/types/ContourSegmentationAnnotation.ts +6 -0
- package/src/types/IToolGroup.ts +1 -1
- package/src/types/ToolSpecificAnnotationTypes.ts +18 -11
- package/src/utilities/contours/interpolation/getInterpolationData.ts +24 -5
- package/src/utilities/contours/interpolation/interpolate.ts +1 -5
- package/src/utilities/contours/interpolation/selectHandles.ts +9 -4
- package/src/utilities/math/line/index.ts +2 -0
- package/src/utilities/math/line/isPointOnLineSegment.ts +44 -0
- package/src/utilities/math/polyline/combinePolyline.ts +5 -7
- package/src/utilities/math/polyline/getLineSegmentIntersectionsCoordinates.ts +2 -2
- package/src/utilities/math/polyline/getLinesIntersection.ts +94 -0
- package/src/utilities/segmentation/InterpolationManager/InterpolationManager.ts +52 -14
- package/dist/cjs/utilities/math/polyline/getLineSegmentsIntersection.d.ts +0 -2
- package/dist/cjs/utilities/math/polyline/getLineSegmentsIntersection.js +0 -21
- package/dist/cjs/utilities/math/polyline/getLineSegmentsIntersection.js.map +0 -1
- package/dist/esm/utilities/math/polyline/getLineSegmentsIntersection.js +0 -18
- package/dist/esm/utilities/math/polyline/getLineSegmentsIntersection.js.map +0 -1
- package/dist/types/utilities/math/polyline/getLineSegmentsIntersection.d.ts +0 -3
- package/dist/types/utilities/math/polyline/getLineSegmentsIntersection.d.ts.map +0 -1
- package/src/utilities/math/polyline/getLineSegmentsIntersection.ts +0 -47
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/tools",
|
|
3
|
-
"version": "1.58.
|
|
3
|
+
"version": "1.58.2",
|
|
4
4
|
"description": "Cornerstone3D Tools",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"webpack:watch": "webpack --mode development --progress --watch --config ./.webpack/webpack.dev.js"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@cornerstonejs/core": "^1.58.
|
|
32
|
+
"@cornerstonejs/core": "^1.58.2",
|
|
33
33
|
"@icr/polyseg-wasm": "0.4.0",
|
|
34
34
|
"@types/offscreencanvas": "2019.7.3",
|
|
35
35
|
"comlink": "^4.4.1",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"type": "individual",
|
|
60
60
|
"url": "https://ohif.org/donate"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "808abe92daab401511e2fbad6328281195a8e297"
|
|
63
63
|
}
|
|
@@ -29,6 +29,7 @@ import { PlanarFreehandContourSegmentationTool } from '../../../tools';
|
|
|
29
29
|
import type { Annotation } from '../../../types';
|
|
30
30
|
import type { ContourAnnotation } from '../../../types/ContourAnnotation';
|
|
31
31
|
import { ContourWindingDirection } from '../../../types/ContourAnnotation';
|
|
32
|
+
import { triggerAnnotationModified } from '../../../stateManagement/annotation/helpers/state';
|
|
32
33
|
|
|
33
34
|
const DEFAULT_CONTOUR_SEG_TOOLNAME = 'PlanarFreehandContourSegmentationTool';
|
|
34
35
|
|
|
@@ -357,6 +358,7 @@ function combinePolylines(
|
|
|
357
358
|
metadata: {
|
|
358
359
|
...metadata,
|
|
359
360
|
toolName: DEFAULT_CONTOUR_SEG_TOOLNAME,
|
|
361
|
+
originalToolName: targetAnnotation.metadata.toolName,
|
|
360
362
|
},
|
|
361
363
|
data: {
|
|
362
364
|
cachedStats: {},
|
|
@@ -368,6 +370,7 @@ function combinePolylines(
|
|
|
368
370
|
polyline: [],
|
|
369
371
|
closed: true,
|
|
370
372
|
},
|
|
373
|
+
spline: targetAnnotation.data.spline,
|
|
371
374
|
segmentation: {
|
|
372
375
|
...segmentation,
|
|
373
376
|
},
|
|
@@ -377,6 +380,10 @@ function combinePolylines(
|
|
|
377
380
|
invalidated: true,
|
|
378
381
|
isLocked: false,
|
|
379
382
|
isVisible: undefined,
|
|
383
|
+
// Allow this object to be interpolated against the original interpolation
|
|
384
|
+
// data.
|
|
385
|
+
interpolationUID: targetAnnotation.interpolationUID,
|
|
386
|
+
interpolationCompleted: targetAnnotation.interpolationCompleted,
|
|
380
387
|
};
|
|
381
388
|
|
|
382
389
|
// Calling `updateContourPolyline` method instead of setting it locally
|
|
@@ -393,6 +400,7 @@ function combinePolylines(
|
|
|
393
400
|
|
|
394
401
|
addAnnotation(newAnnotation, element);
|
|
395
402
|
contourSegUtils.addContourSegmentationAnnotation(newAnnotation);
|
|
403
|
+
triggerAnnotationModified(newAnnotation, viewport.element);
|
|
396
404
|
|
|
397
405
|
reassignedContourHolesMap
|
|
398
406
|
.get(polyline)
|
|
@@ -4,6 +4,8 @@ import { ContourAnnotation } from './ContourAnnotation';
|
|
|
4
4
|
|
|
5
5
|
export type ContourSegmentationAnnotationData = {
|
|
6
6
|
autoGenerated?: boolean;
|
|
7
|
+
interpolationUID?: string;
|
|
8
|
+
interpolationCompleted?: boolean;
|
|
7
9
|
data: {
|
|
8
10
|
segmentation: {
|
|
9
11
|
segmentationId: string;
|
|
@@ -16,6 +18,10 @@ export type ContourSegmentationAnnotationData = {
|
|
|
16
18
|
originalPolyline?: Types.Point3[];
|
|
17
19
|
};
|
|
18
20
|
};
|
|
21
|
+
metadata?: {
|
|
22
|
+
/** The original name of the tool before adding/removing holes and contours */
|
|
23
|
+
originalToolName?: string;
|
|
24
|
+
};
|
|
19
25
|
handles?: {
|
|
20
26
|
/**
|
|
21
27
|
* Segmentation contours can be interpolated between slices to produce
|
package/src/types/IToolGroup.ts
CHANGED
|
@@ -44,7 +44,7 @@ export default interface IToolGroup {
|
|
|
44
44
|
};
|
|
45
45
|
/** Setting the tool to be Passive by its name*/
|
|
46
46
|
setToolPassive: {
|
|
47
|
-
(toolName: string): void;
|
|
47
|
+
(toolName: string, options?: { removeAllBindings?: boolean }): void;
|
|
48
48
|
};
|
|
49
49
|
/** Setting the tool to be Enabled by its name*/
|
|
50
50
|
setToolEnabled: {
|
|
@@ -260,18 +260,25 @@ export type PlanarFreehandROIAnnotation = ContourAnnotation & {
|
|
|
260
260
|
export type PlanarFreehandContourSegmentationAnnotation =
|
|
261
261
|
PlanarFreehandROIAnnotation & ContourSegmentationAnnotationData;
|
|
262
262
|
|
|
263
|
-
export type InterpolationROIAnnotation = ContourAnnotation &
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
export type InterpolationROIAnnotation = ContourAnnotation &
|
|
264
|
+
ContourSegmentationAnnotationData & {
|
|
265
|
+
metadata: {
|
|
266
|
+
annotationUID?: string;
|
|
267
|
+
};
|
|
268
|
+
/** The interpolationUID links contours which are interpolated together */
|
|
269
|
+
interpolationUID?: string;
|
|
270
|
+
/**
|
|
271
|
+
* The interpolation completed flag is used to mark interpolations as being done
|
|
272
|
+
* and no longer elligible for matching.
|
|
273
|
+
*/
|
|
274
|
+
interpolationCompleted?: boolean;
|
|
275
|
+
/**
|
|
276
|
+
* A flag to track updates to annotations caused by things like
|
|
277
|
+
* spline or livewire regeenration of the data, and which should cause further
|
|
278
|
+
* updates to occur (or not as the tool decides).
|
|
279
|
+
*/
|
|
280
|
+
isInterpolationUpdate?: boolean;
|
|
266
281
|
};
|
|
267
|
-
interpolationUID?: string;
|
|
268
|
-
/**
|
|
269
|
-
* A flag to track updates to annotations caused by things like
|
|
270
|
-
* spline or livewire regeenration of the data, and which should cause further
|
|
271
|
-
* updates to occur (or not as the tool decides).
|
|
272
|
-
*/
|
|
273
|
-
isInterpolationUpdate?: boolean;
|
|
274
|
-
};
|
|
275
282
|
|
|
276
283
|
export interface ArrowAnnotation extends Annotation {
|
|
277
284
|
data: {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
InterpolationViewportData,
|
|
3
|
+
Annotation,
|
|
4
|
+
ContourSegmentationAnnotation,
|
|
5
|
+
} from '../../../types';
|
|
2
6
|
import { getAnnotations } from '../../../stateManagement/annotation/annotationState';
|
|
3
|
-
|
|
7
|
+
|
|
8
|
+
const DEFAULT_CONTOUR_SEG_TOOLNAME = 'PlanarFreehandContourSegmentationTool';
|
|
4
9
|
|
|
5
10
|
export type FilterParam = {
|
|
6
11
|
/**
|
|
@@ -38,12 +43,26 @@ export default function getInterpolationData(
|
|
|
38
43
|
): Map<number, Annotation[]> {
|
|
39
44
|
const { viewport, sliceData, annotation } = viewportData;
|
|
40
45
|
const interpolationDatas = new Map<number, Annotation[]>();
|
|
41
|
-
const
|
|
42
|
-
|
|
46
|
+
const { toolName, originalToolName } = annotation.metadata;
|
|
47
|
+
const testToolName = originalToolName || toolName;
|
|
48
|
+
const annotations = getAnnotations(testToolName, viewport.element) || [];
|
|
49
|
+
const modifiedAnnotations = getAnnotations(
|
|
50
|
+
DEFAULT_CONTOUR_SEG_TOOLNAME,
|
|
43
51
|
viewport.element
|
|
44
52
|
);
|
|
53
|
+
if (modifiedAnnotations?.length) {
|
|
54
|
+
modifiedAnnotations.forEach((annotation) => {
|
|
55
|
+
const { metadata } = annotation as ContourSegmentationAnnotation;
|
|
56
|
+
if (
|
|
57
|
+
metadata.originalToolName === testToolName &&
|
|
58
|
+
!annotations.find((it) => it === annotation)
|
|
59
|
+
) {
|
|
60
|
+
annotations.push(annotation);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
45
64
|
|
|
46
|
-
if (!annotations) {
|
|
65
|
+
if (!annotations?.length) {
|
|
47
66
|
return interpolationDatas;
|
|
48
67
|
}
|
|
49
68
|
|
|
@@ -28,8 +28,6 @@ export type PointsArray3 = Types.PointsManager<Types.Point3> & {
|
|
|
28
28
|
|
|
29
29
|
const dP = 0.2; // Aim for < 0.2mm between interpolated nodes when super-sampling.
|
|
30
30
|
|
|
31
|
-
let interpolating = false;
|
|
32
|
-
|
|
33
31
|
/**
|
|
34
32
|
* interpolate - Interpolate missing contours in the ROIContours.
|
|
35
33
|
* If input is tool data collection, it is expected to be sorted in the order
|
|
@@ -44,10 +42,9 @@ let interpolating = false;
|
|
|
44
42
|
* @returns null
|
|
45
43
|
*/
|
|
46
44
|
function interpolate(viewportData: InterpolationViewportData) {
|
|
47
|
-
if (
|
|
45
|
+
if (!viewportData.annotation) {
|
|
48
46
|
return;
|
|
49
47
|
}
|
|
50
|
-
interpolating = true;
|
|
51
48
|
const { isInterpolationUpdate, annotation } = viewportData;
|
|
52
49
|
queueMicrotask(() => {
|
|
53
50
|
try {
|
|
@@ -59,7 +56,6 @@ function interpolate(viewportData: InterpolationViewportData) {
|
|
|
59
56
|
}
|
|
60
57
|
startInterpolation(viewportData);
|
|
61
58
|
} finally {
|
|
62
|
-
interpolating = false;
|
|
63
59
|
if (isInterpolationUpdate) {
|
|
64
60
|
// Reset the auto generated flag
|
|
65
61
|
annotation.autoGenerated = true;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { vec3 } from 'gl-matrix';
|
|
2
2
|
import { utilities } from '@cornerstonejs/core';
|
|
3
3
|
import type { PointsArray3 } from './interpolate';
|
|
4
|
-
import { add } from '@kitware/vtk.js/Common/Core/Math';
|
|
5
4
|
|
|
6
5
|
const { PointsManager } = utilities;
|
|
7
6
|
|
|
@@ -15,18 +14,24 @@ const { PointsManager } = utilities;
|
|
|
15
14
|
*/
|
|
16
15
|
export default function selectHandles(
|
|
17
16
|
polyline: PointsArray3,
|
|
18
|
-
handleCount =
|
|
17
|
+
handleCount = 12
|
|
19
18
|
): PointsArray3 {
|
|
20
19
|
const handles = PointsManager.create3(handleCount) as PointsArray3;
|
|
21
20
|
handles.sources = [];
|
|
22
21
|
const { sources: destPoints } = handles;
|
|
23
22
|
const { length, sources: sourcePoints = [] } = polyline;
|
|
23
|
+
// The distance used for figuring out the local angle of a line
|
|
24
24
|
const distance = 6;
|
|
25
25
|
if (length < distance * 3) {
|
|
26
|
-
console.log('Adding subselect handles', handleCount, length);
|
|
27
26
|
return polyline.subselect(handleCount);
|
|
28
27
|
}
|
|
29
|
-
|
|
28
|
+
// Need to make the interval between handles long enough to allow for some
|
|
29
|
+
// variation between points in terms of the distance of a line angle, but
|
|
30
|
+
// also not too many handles either.
|
|
31
|
+
// On average, we get twice the interval between handles, so double the length here.
|
|
32
|
+
const interval = Math.floor(
|
|
33
|
+
Math.max((2 * length) / handleCount, distance * 5)
|
|
34
|
+
);
|
|
30
35
|
sourcePoints.forEach(() =>
|
|
31
36
|
destPoints.push(PointsManager.create3(handleCount))
|
|
32
37
|
);
|
|
@@ -2,10 +2,12 @@ import distanceToPoint from './distanceToPoint';
|
|
|
2
2
|
import distanceToPointSquared from './distanceToPointSquared';
|
|
3
3
|
import distanceToPointSquaredInfo from './distanceToPointSquaredInfo';
|
|
4
4
|
import intersectLine from './intersectLine';
|
|
5
|
+
import isPointOnLineSegment from './isPointOnLineSegment';
|
|
5
6
|
|
|
6
7
|
export {
|
|
7
8
|
distanceToPoint,
|
|
8
9
|
distanceToPointSquared,
|
|
9
10
|
distanceToPointSquaredInfo,
|
|
10
11
|
intersectLine,
|
|
12
|
+
isPointOnLineSegment,
|
|
11
13
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Types } from '@cornerstonejs/core';
|
|
2
|
+
|
|
3
|
+
const ORIENTATION_TOLERANCE = 1e-2;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Test if a point is on a line segment
|
|
7
|
+
* @param lineStart - Line segment start point
|
|
8
|
+
* @param lineEnd - Line segment end point
|
|
9
|
+
* @param point - Point to test
|
|
10
|
+
* @returns True if the point lies on the line segment or false otherwise
|
|
11
|
+
*/
|
|
12
|
+
export default function isPointOnLineSegment(
|
|
13
|
+
lineStart: Types.Point2,
|
|
14
|
+
lineEnd: Types.Point2,
|
|
15
|
+
point: Types.Point2
|
|
16
|
+
): boolean {
|
|
17
|
+
// The code below runs ~4x faster than calling `line.distanceToPointSquared()` (155 vs 598 ms)
|
|
18
|
+
|
|
19
|
+
// No Math.min/max call for better performance when testing thousands of points
|
|
20
|
+
const minX = lineStart[0] <= lineEnd[0] ? lineStart[0] : lineEnd[0];
|
|
21
|
+
const maxX = lineStart[0] >= lineEnd[0] ? lineStart[0] : lineEnd[0];
|
|
22
|
+
const minY = lineStart[1] <= lineEnd[1] ? lineStart[1] : lineEnd[1];
|
|
23
|
+
const maxY = lineStart[1] >= lineEnd[1] ? lineStart[1] : lineEnd[1];
|
|
24
|
+
|
|
25
|
+
// Checks if the point lies inside the AABB
|
|
26
|
+
const aabbContainsPoint =
|
|
27
|
+
point[0] >= minX - ORIENTATION_TOLERANCE &&
|
|
28
|
+
point[0] <= maxX + ORIENTATION_TOLERANCE &&
|
|
29
|
+
point[1] >= minY - ORIENTATION_TOLERANCE &&
|
|
30
|
+
point[1] <= maxY + ORIENTATION_TOLERANCE;
|
|
31
|
+
|
|
32
|
+
if (!aabbContainsPoint) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Now that we know the point is inside the AABB we check if it lies on the line segment
|
|
37
|
+
const orientation =
|
|
38
|
+
(lineEnd[1] - lineStart[1]) * (point[0] - lineEnd[0]) -
|
|
39
|
+
(lineEnd[0] - lineStart[0]) * (point[1] - lineEnd[1]);
|
|
40
|
+
const absOrientation = orientation >= 0 ? orientation : -orientation;
|
|
41
|
+
|
|
42
|
+
// The orientation must be zero for points that lies on the same line
|
|
43
|
+
return absOrientation <= ORIENTATION_TOLERANCE;
|
|
44
|
+
}
|
|
@@ -4,7 +4,7 @@ import getLineSegmentIntersectionsIndexes from './getLineSegmentIntersectionsInd
|
|
|
4
4
|
import containsPoint from './containsPoint';
|
|
5
5
|
import getNormal2 from './getNormal2';
|
|
6
6
|
import { glMatrix, vec3 } from 'gl-matrix';
|
|
7
|
-
import
|
|
7
|
+
import getLinesIntersection from './getLinesIntersection';
|
|
8
8
|
|
|
9
9
|
enum PolylinePointType {
|
|
10
10
|
Vertex,
|
|
@@ -106,12 +106,10 @@ function getSourceAndTargetPointsList(
|
|
|
106
106
|
const p2 = sourcePolyline[intersectedLineSegment[0]];
|
|
107
107
|
const q2 = sourcePolyline[intersectedLineSegment[1]];
|
|
108
108
|
|
|
109
|
-
// lineSegment.intersectLine returns
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
|
|
113
|
-
// - [(0, 1), (2, 1)] x [(1, 1), (1, 2)]
|
|
114
|
-
const intersectionCoordinate = getLineSegmentsIntersection(
|
|
109
|
+
// lineSegment.intersectLine returns the midpoint of the four points
|
|
110
|
+
// when the lines are parallel or co-incident. Otherwise it will return
|
|
111
|
+
// an extension of the line.
|
|
112
|
+
const intersectionCoordinate = getLinesIntersection(
|
|
115
113
|
p1,
|
|
116
114
|
q1,
|
|
117
115
|
p2,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Types } from '@cornerstonejs/core';
|
|
2
2
|
import getLineSegmentIntersectionsIndexes from './getLineSegmentIntersectionsIndexes';
|
|
3
|
-
import
|
|
3
|
+
import getLinesIntersection from './getLinesIntersection';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Returns all intersections points between a line segment and a polyline
|
|
@@ -22,7 +22,7 @@ export default function getLineSegmentIntersectionsCoordinates(
|
|
|
22
22
|
for (let i = 0; i < polylineIndexes.length; i++) {
|
|
23
23
|
const p2 = points[polylineIndexes[i][0]];
|
|
24
24
|
const q2 = points[polylineIndexes[i][1]];
|
|
25
|
-
const intersection =
|
|
25
|
+
const intersection = getLinesIntersection(p1, q1, p2, q2);
|
|
26
26
|
result.push(intersection);
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Types } from '@cornerstonejs/core';
|
|
2
|
+
import * as mathLine from '../line';
|
|
3
|
+
|
|
4
|
+
// ATTENTION: this is an internal function and it should not be added to "polyline" namespace
|
|
5
|
+
|
|
6
|
+
// Tested with +1M random overlapping line segments and any tolerance below this
|
|
7
|
+
// one may return invalid results.
|
|
8
|
+
const PARALLEL_LINES_TOLERANCE = 1e-2;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* It returns the intersection between two lines (not line segments) or a midpoint
|
|
12
|
+
* when the line segments overlap. This function calculates the intersection between
|
|
13
|
+
* lines because it considers that getFirstLineSegmentIntersectionIndexes,
|
|
14
|
+
* getLineSegmentIntersectionsCoordinates or getLineSegmentIntersectionsIndexes
|
|
15
|
+
* has already been called first which guarantees.
|
|
16
|
+
*
|
|
17
|
+
* @param p1 - Line segment 1 start
|
|
18
|
+
* @param q1 - Line segment 1 end
|
|
19
|
+
* @param p2 - Line segment 2 start
|
|
20
|
+
* @param q2 - Line segment 21 end
|
|
21
|
+
* @returns The intersection between two lines or a midpoint when they overlap
|
|
22
|
+
*/
|
|
23
|
+
export default function getLinesIntersection(
|
|
24
|
+
p1: Types.Point2,
|
|
25
|
+
q1: Types.Point2,
|
|
26
|
+
p2: Types.Point2,
|
|
27
|
+
q2: Types.Point2
|
|
28
|
+
) {
|
|
29
|
+
const diffQ1P1 = [q1[0] - p1[0], q1[1] - p1[1]];
|
|
30
|
+
const diffQ2P2 = [q2[0] - p2[0], q2[1] - p2[1]];
|
|
31
|
+
const denominator = diffQ2P2[1] * diffQ1P1[0] - diffQ2P2[0] * diffQ1P1[1];
|
|
32
|
+
const absDenominator = denominator >= 0 ? denominator : -denominator;
|
|
33
|
+
|
|
34
|
+
if (absDenominator < PARALLEL_LINES_TOLERANCE) {
|
|
35
|
+
// No Math.min/max calls for better performance.
|
|
36
|
+
const line1AABB = [
|
|
37
|
+
p1[0] < q1[0] ? p1[0] : q1[0], // 0: minX
|
|
38
|
+
p1[0] > q1[0] ? p1[0] : q1[0], // 1: maxX
|
|
39
|
+
p1[1] < q1[1] ? p1[1] : q1[1], // 2: minY
|
|
40
|
+
p1[1] > q1[1] ? p1[1] : q1[1], // 3: maxY
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// No Math.min/max calls for better performance.
|
|
44
|
+
const line2AABB = [
|
|
45
|
+
p2[0] < q2[0] ? p2[0] : q2[0], // 0: minX
|
|
46
|
+
p2[0] > q2[0] ? p2[0] : q2[0], // 1: maxX
|
|
47
|
+
p2[1] < q2[1] ? p2[1] : q2[1], // 2: minY
|
|
48
|
+
p2[1] > q2[1] ? p2[1] : q2[1], // 3: maxY
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const aabbIntersects =
|
|
52
|
+
line1AABB[0] <= line2AABB[1] && // minX1 <= maxX2
|
|
53
|
+
line1AABB[1] >= line2AABB[0] && // maxX1 >= minX2
|
|
54
|
+
line1AABB[2] <= line2AABB[3] && // minY1 <= maxY2
|
|
55
|
+
line1AABB[3] >= line2AABB[2]; // maxY1 >= minY2
|
|
56
|
+
|
|
57
|
+
if (!aabbIntersects) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Three tests are enough to know if the lines overlap
|
|
62
|
+
const overlap =
|
|
63
|
+
mathLine.isPointOnLineSegment(p1, q1, p2) ||
|
|
64
|
+
mathLine.isPointOnLineSegment(p1, q1, q2) ||
|
|
65
|
+
mathLine.isPointOnLineSegment(p2, q2, p1);
|
|
66
|
+
|
|
67
|
+
if (!overlap) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// min/max seems to be inverted but that is correct because it is looking
|
|
72
|
+
// for the intersection range. No Math.min/max calls for better performance.
|
|
73
|
+
const minX = line1AABB[0] > line2AABB[0] ? line1AABB[0] : line2AABB[0];
|
|
74
|
+
const maxX = line1AABB[1] < line2AABB[1] ? line1AABB[1] : line2AABB[1];
|
|
75
|
+
const minY = line1AABB[2] > line2AABB[2] ? line1AABB[2] : line2AABB[2];
|
|
76
|
+
const maxY = line1AABB[3] < line2AABB[3] ? line1AABB[3] : line2AABB[3];
|
|
77
|
+
const midX = (minX + maxX) * 0.5;
|
|
78
|
+
const midY = (minY + maxY) * 0.5;
|
|
79
|
+
|
|
80
|
+
return [midX, midY];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let a = p1[1] - p2[1];
|
|
84
|
+
let b = p1[0] - p2[0];
|
|
85
|
+
const numerator1 = diffQ2P2[0] * a - diffQ2P2[1] * b;
|
|
86
|
+
const numerator2 = diffQ1P1[0] * a - diffQ1P1[1] * b;
|
|
87
|
+
a = numerator1 / denominator;
|
|
88
|
+
b = numerator2 / denominator;
|
|
89
|
+
|
|
90
|
+
const resultX = p1[0] + a * diffQ1P1[0];
|
|
91
|
+
const resultY = p1[1] + a * diffQ1P1[1];
|
|
92
|
+
|
|
93
|
+
return [resultX, resultY];
|
|
94
|
+
}
|
|
@@ -17,6 +17,7 @@ import deleteRelatedAnnotations from './deleteRelatedAnnotations';
|
|
|
17
17
|
import { InterpolationROIAnnotation } from '../../../types/ToolSpecificAnnotationTypes';
|
|
18
18
|
import ChangeTypes from '../../../enums/ChangeTypes';
|
|
19
19
|
import getViewportForAnnotation from '../../getViewportForAnnotation';
|
|
20
|
+
import { addContourSegmentationAnnotation } from '../../contourSegmentation/addContourSegmentationAnnotation';
|
|
20
21
|
|
|
21
22
|
const { uuidv4 } = csUtils;
|
|
22
23
|
|
|
@@ -69,12 +70,15 @@ export default class InterpolationManager {
|
|
|
69
70
|
const annotations = annotationState.getAnnotations(
|
|
70
71
|
toolName,
|
|
71
72
|
annotationGroupSelector
|
|
72
|
-
);
|
|
73
|
+
) as InterpolationROIAnnotation[];
|
|
73
74
|
if (!annotations?.length) {
|
|
74
75
|
continue;
|
|
75
76
|
}
|
|
76
77
|
for (const annotation of annotations) {
|
|
77
|
-
const { data, autoGenerated, metadata } = annotation;
|
|
78
|
+
const { interpolationUID, data, autoGenerated, metadata } = annotation;
|
|
79
|
+
if (interpolationUID) {
|
|
80
|
+
annotation.interpolationCompleted = true;
|
|
81
|
+
}
|
|
78
82
|
if (!autoGenerated) {
|
|
79
83
|
continue;
|
|
80
84
|
}
|
|
@@ -94,21 +98,31 @@ export default class InterpolationManager {
|
|
|
94
98
|
) {
|
|
95
99
|
continue;
|
|
96
100
|
}
|
|
101
|
+
addContourSegmentationAnnotation(annotation);
|
|
97
102
|
annotation.autoGenerated = false;
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
105
|
}
|
|
101
106
|
|
|
107
|
+
/**
|
|
108
|
+
* When an annotation is completed, if the configuration includes interpolation,
|
|
109
|
+
* then find matching interpolations and interpolation between this segmentation
|
|
110
|
+
* and the other segmentations of the same type.
|
|
111
|
+
*/
|
|
102
112
|
static handleAnnotationCompleted = (evt: AnnotationCompletedEventType) => {
|
|
103
113
|
const annotation = evt.detail.annotation as InterpolationROIAnnotation;
|
|
104
114
|
if (!annotation?.metadata) {
|
|
105
115
|
return;
|
|
106
116
|
}
|
|
107
|
-
const { toolName } = annotation.metadata;
|
|
117
|
+
const { toolName, originalToolName } = annotation.metadata;
|
|
108
118
|
|
|
109
|
-
if (
|
|
119
|
+
if (
|
|
120
|
+
!this.toolNames.includes(toolName) &&
|
|
121
|
+
!this.toolNames.includes(originalToolName)
|
|
122
|
+
) {
|
|
110
123
|
return;
|
|
111
124
|
}
|
|
125
|
+
console.log('Interpolation annotation', annotation.annotationUID);
|
|
112
126
|
|
|
113
127
|
const viewport = getViewportForAnnotation(annotation);
|
|
114
128
|
if (!viewport) {
|
|
@@ -153,28 +167,45 @@ export default class InterpolationManager {
|
|
|
153
167
|
viewportData,
|
|
154
168
|
filterData
|
|
155
169
|
);
|
|
156
|
-
// Skip other type of
|
|
170
|
+
// Skip other type of annotation interpolationUID's that are co-located
|
|
171
|
+
const { sliceIndex } = annotation.metadata;
|
|
172
|
+
const skipUIDs = new Set<string>();
|
|
173
|
+
interpolationAnnotations.forEach((interpolationAnnotation) => {
|
|
174
|
+
if (
|
|
175
|
+
interpolationAnnotation.interpolationCompleted ||
|
|
176
|
+
interpolationAnnotation.metadata.sliceIndex === sliceIndex
|
|
177
|
+
) {
|
|
178
|
+
const { interpolationUID } = interpolationAnnotation;
|
|
179
|
+
skipUIDs.add(interpolationUID);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
157
182
|
interpolationAnnotations = interpolationAnnotations.filter(
|
|
158
|
-
(interpolationAnnotation) =>
|
|
183
|
+
(interpolationAnnotation) =>
|
|
184
|
+
!skipUIDs.has(interpolationAnnotation.interpolationUID)
|
|
159
185
|
);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
186
|
+
|
|
187
|
+
// Assign a new interpolationUID (this is checked above, so will be empty initially)
|
|
188
|
+
annotation.interpolationUID =
|
|
189
|
+
interpolationAnnotations[0]?.interpolationUID || uuidv4();
|
|
190
|
+
viewportData.interpolationUID = annotation.interpolationUID;
|
|
165
191
|
interpolate(viewportData);
|
|
166
192
|
};
|
|
167
193
|
|
|
194
|
+
/**
|
|
195
|
+
* This method gets called when an annotation changes. It will then trigger
|
|
196
|
+
* related already interpolated annotations to be updated with the modified data.
|
|
197
|
+
*/
|
|
168
198
|
static handleAnnotationUpdate = (evt: AnnotationModifiedEventType) => {
|
|
169
199
|
const annotation = evt.detail.annotation as InterpolationROIAnnotation;
|
|
170
200
|
const { changeType = ChangeTypes.HandlesUpdated } = evt.detail;
|
|
171
201
|
if (!annotation?.metadata) {
|
|
172
202
|
return;
|
|
173
203
|
}
|
|
174
|
-
const { toolName } = annotation.metadata;
|
|
204
|
+
const { toolName, originalToolName } = annotation.metadata;
|
|
175
205
|
|
|
176
206
|
if (
|
|
177
|
-
!this.toolNames.includes(toolName)
|
|
207
|
+
(!this.toolNames.includes(toolName) &&
|
|
208
|
+
!this.toolNames.includes(originalToolName)) ||
|
|
178
209
|
!ChangeTypesForInterpolation.includes(changeType)
|
|
179
210
|
) {
|
|
180
211
|
return;
|
|
@@ -188,7 +219,11 @@ export default class InterpolationManager {
|
|
|
188
219
|
);
|
|
189
220
|
return;
|
|
190
221
|
}
|
|
191
|
-
annotation.autoGenerated
|
|
222
|
+
if (annotation.autoGenerated) {
|
|
223
|
+
// Dont fire the annotation changed events here, as that leads to recursion.
|
|
224
|
+
addContourSegmentationAnnotation(annotation);
|
|
225
|
+
annotation.autoGenerated = false;
|
|
226
|
+
}
|
|
192
227
|
|
|
193
228
|
const sliceData: Types.ImageSliceData = getSliceData(viewport);
|
|
194
229
|
const viewportData: InterpolationViewportData = {
|
|
@@ -201,6 +236,9 @@ export default class InterpolationManager {
|
|
|
201
236
|
interpolate(viewportData);
|
|
202
237
|
};
|
|
203
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Delete interpolated annotations when their endpoints are deleted.
|
|
241
|
+
*/
|
|
204
242
|
static handleAnnotationDelete = (evt: AnnotationRemovedEventType) => {
|
|
205
243
|
const annotation = evt.detail.annotation as InterpolationROIAnnotation;
|
|
206
244
|
if (!annotation?.metadata) {
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
function getLineSegmentsIntersection(p1, q1, p2, q2) {
|
|
4
|
-
const diffQ1P1 = [q1[0] - p1[0], q1[1] - p1[1]];
|
|
5
|
-
const diffQ2P2 = [q2[0] - p2[0], q2[1] - p2[1]];
|
|
6
|
-
const denominator = diffQ2P2[1] * diffQ1P1[0] - diffQ2P2[0] * diffQ1P1[1];
|
|
7
|
-
if (denominator == 0) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
let a = p1[1] - p2[1];
|
|
11
|
-
let b = p1[0] - p2[0];
|
|
12
|
-
const numerator1 = diffQ2P2[0] * a - diffQ2P2[1] * b;
|
|
13
|
-
const numerator2 = diffQ1P1[0] * a - diffQ1P1[1] * b;
|
|
14
|
-
a = numerator1 / denominator;
|
|
15
|
-
b = numerator2 / denominator;
|
|
16
|
-
const resultX = p1[0] + a * diffQ1P1[0];
|
|
17
|
-
const resultY = p1[1] + a * diffQ1P1[1];
|
|
18
|
-
return [resultX, resultY];
|
|
19
|
-
}
|
|
20
|
-
exports.default = getLineSegmentsIntersection;
|
|
21
|
-
//# sourceMappingURL=getLineSegmentsIntersection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getLineSegmentsIntersection.js","sourceRoot":"","sources":["../../../../../src/utilities/math/polyline/getLineSegmentsIntersection.ts"],"names":[],"mappings":";;AAqBA,SAAwB,2BAA2B,CACjD,EAAgB,EAChB,EAAgB,EAChB,EAAgB,EAChB,EAAgB;IAEhB,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE1E,IAAI,WAAW,IAAI,CAAC,EAAE;QACpB,OAAO;KACR;IAED,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7B,CAAC,GAAG,UAAU,GAAG,WAAW,CAAC;IAE7B,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAzBD,8CAyBC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export default function getLineSegmentsIntersection(p1, q1, p2, q2) {
|
|
2
|
-
const diffQ1P1 = [q1[0] - p1[0], q1[1] - p1[1]];
|
|
3
|
-
const diffQ2P2 = [q2[0] - p2[0], q2[1] - p2[1]];
|
|
4
|
-
const denominator = diffQ2P2[1] * diffQ1P1[0] - diffQ2P2[0] * diffQ1P1[1];
|
|
5
|
-
if (denominator == 0) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
let a = p1[1] - p2[1];
|
|
9
|
-
let b = p1[0] - p2[0];
|
|
10
|
-
const numerator1 = diffQ2P2[0] * a - diffQ2P2[1] * b;
|
|
11
|
-
const numerator2 = diffQ1P1[0] * a - diffQ1P1[1] * b;
|
|
12
|
-
a = numerator1 / denominator;
|
|
13
|
-
b = numerator2 / denominator;
|
|
14
|
-
const resultX = p1[0] + a * diffQ1P1[0];
|
|
15
|
-
const resultY = p1[1] + a * diffQ1P1[1];
|
|
16
|
-
return [resultX, resultY];
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=getLineSegmentsIntersection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getLineSegmentsIntersection.js","sourceRoot":"","sources":["../../../../../src/utilities/math/polyline/getLineSegmentsIntersection.ts"],"names":[],"mappings":"AAqBA,MAAM,CAAC,OAAO,UAAU,2BAA2B,CACjD,EAAgB,EAChB,EAAgB,EAChB,EAAgB,EAChB,EAAgB;IAEhB,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE1E,IAAI,WAAW,IAAI,CAAC,EAAE;QACpB,OAAO;KACR;IAED,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7B,CAAC,GAAG,UAAU,GAAG,WAAW,CAAC;IAE7B,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getLineSegmentsIntersection.d.ts","sourceRoot":"","sources":["../../../../../src/utilities/math/polyline/getLineSegmentsIntersection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAqB5C,MAAM,CAAC,OAAO,UAAU,2BAA2B,CACjD,EAAE,EAAE,KAAK,CAAC,MAAM,EAChB,EAAE,EAAE,KAAK,CAAC,MAAM,EAChB,EAAE,EAAE,KAAK,CAAC,MAAM,EAChB,EAAE,EAAE,KAAK,CAAC,MAAM,GACf,KAAK,CAAC,MAAM,CAoBd"}
|