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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | 428x | import { utilities as csUtils } from '@cornerstonejs/core'; import type { Types } from '@cornerstonejs/core'; /** * Returns a point based on some criteria (e.g., minimum or maximum intensity) in * the line of sight (on the line between the passed worldPosition and camera position). * It iterated over the points with a step size on the line. * * @param viewport - Volume viewport * @param worldPos - World coordinates of the clicked location * @param targetVolumeId - target Volume ID in the viewport * @param criteriaFunction - A function that returns the point if it passes a certain * written logic, for instance, it can be a maxValue function that keeps the * records of all intensity values, and only return the point if its intensity * is greater than the maximum intensity of the points passed before. * @param stepsSize - Percentage of the spacing in the normal direction, default value * is 0.25 which means steps = 1/4 of the spacing in the normal direction. * @returns the World pos of the point that passes the criteriaFunction */ export function getPointInLineOfSightWithCriteria( viewport: Types.IVolumeViewport, worldPos: Types.Point3, targetVolumeId: string, criteriaFunction: (intensity: number, point: Types.Point3) => Types.Point3, stepSize = 0.25 ): Types.Point3 { const points = getPointsInLineOfSight(viewport, worldPos, { targetVolumeId, stepSize, }); let pickedPoint; for (const point of points) { const intensity = viewport.getIntensityFromWorld(point); const pointToPick = criteriaFunction(intensity, point); if (pointToPick) { pickedPoint = pointToPick; } } return pickedPoint; } /** * Calculates and returns an array of points in the line of sight between the camera and a target volume. * @param viewport - The volume viewport. * @param worldPos - The world position of the camera. * @param targetVolumeId - The ID of the target volume. * @param stepSize - The step size for iterating along the line of sight. Default is 0.25. * @returns An array of points in the line of sight. */ export function getPointsInLineOfSight( viewport: Types.IVolumeViewport, worldPos: Types.Point3, { targetVolumeId, stepSize }: { targetVolumeId: string; stepSize: number } ): Types.Point3[] { const camera = viewport.getCamera(); const { viewPlaneNormal: normalDirection } = camera; const { spacingInNormalDirection } = csUtils.getTargetVolumeAndSpacingInNormalDir( viewport, camera, targetVolumeId ); const step = spacingInNormalDirection * stepSize || 1; const bounds = viewport.getBounds(); const points: Types.Point3[] = []; // Sample points in the positive normal direction let currentPos = [...worldPos] as Types.Point3; while (_inBounds(currentPos, bounds)) { points.push([...currentPos]); currentPos[0] += normalDirection[0] * step; currentPos[1] += normalDirection[1] * step; currentPos[2] += normalDirection[2] * step; } // Sample points in the negative normal direction currentPos = [...worldPos]; while (_inBounds(currentPos, bounds)) { points.push([...currentPos]); currentPos[0] -= normalDirection[0] * step; currentPos[1] -= normalDirection[1] * step; currentPos[2] -= normalDirection[2] * step; } return points; } /** * Returns whether the point in the world is inside the bounds of the viewport * @param point - coordinates in the world * @returns boolean */ const _inBounds = function ( point: Types.Point3, bounds: Array<number> ): boolean { const [xMin, xMax, yMin, yMax, zMin, zMax] = bounds; const padding = 10; return ( point[0] > xMin + padding && point[0] < xMax - padding && point[1] > yMin + padding && point[1] < yMax - padding && point[2] > zMin + padding && point[2] < zMax - padding ); }; |