Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | import { Types } from '@cornerstonejs/core';
import { interpolatePoints } from './algorithms/bspline';
/**
* Returns a list of uniform distributed values. This list contains the max amount of values which has at least a minimum distance between two consecutive values.
* minDistributionDistance means the min distance between two consecutive distributed values.
* Closed interval contains the min/max values.
*
* Formula for reference
* For given {x ∈ R | x ≥ 0} and {minDis ∈ R | minDis ≥ 0}, ∃ D(x) where D(x) ≥ a and D(x) ≤ b =>
* |
* D(x) = | (b - a)
* | round( ------------------------ * x ) + a
* | (b - a + 1)
* | round( ----------- )
* | minDis
*/
function getContinuousUniformDistributionValues(
minDistributionDistance: number,
closedInterval: [number, number]
): number[] {
const result = [];
const [intervalIni, intervalEnd] = closedInterval;
const intervalSize = intervalEnd - intervalIni + 1;
const intensity = Math.floor(intervalSize / minDistributionDistance);
let x = 0;
let continuosDistributionValue =
Math.round(((intervalSize - 1) / (intensity - 1)) * x) + intervalIni;
while (continuosDistributionValue <= intervalEnd) {
result.push(continuosDistributionValue);
x++;
continuosDistributionValue =
Math.round(((intervalSize - 1) / (intensity - 1)) * x) + intervalIni;
}
return result;
}
/**
* Interpolates a segment of points from iniIndex until endIndex.
* The process of interpolation considers the param knotsRatioPercentage as being the percentage of points from Segment that are likely to be considered.
* By default it uses b-spline algorithm.
* The result total of points is equal to original points.
*/
export default function interpolateSegmentPoints(
points: (Types.Point2 | Types.Point3)[],
iniIndex: number,
endIndex: number,
knotsRatioPercentage: number
): (Types.Point2 | Types.Point3)[] {
const segmentSize = endIndex - iniIndex + 1;
const amountOfKnots =
Math.floor((knotsRatioPercentage / 100) * segmentSize) ?? 1;
const minKnotDistance = Math.floor(segmentSize / amountOfKnots) ?? 1;
if (isNaN(segmentSize) || !segmentSize || !minKnotDistance) {
return points;
}
// segment should be at least the double of desired minKnot distance. This will ensure at there will enough knots to interpolate.
if (segmentSize / minKnotDistance < 2) {
return points;
}
const interpolationIniIndex = Math.max(0, iniIndex);
const interpolationEndIndex = Math.min(points.length - 1, endIndex);
const segmentPointsUnchangedBeg = points.slice(0, interpolationIniIndex);
const segmentPointsUnchangedEnd = points.slice(
interpolationEndIndex + 1,
points.length
);
const knotsIndexes = getContinuousUniformDistributionValues(minKnotDistance, [
interpolationIniIndex,
interpolationEndIndex,
]);
const interpolatedPoints = interpolatePoints(points, knotsIndexes);
return [
...segmentPointsUnchangedBeg,
...interpolatedPoints,
...segmentPointsUnchangedEnd,
];
}
|