UNPKG

@cornerstonejs/core

Version:
105 lines (104 loc) 4.19 kB
import ResolvedViewportView from '../ResolvedViewportView.js'; import { canvasToIndexForWSI, indexToCanvasForWSI, indexToWorldWSIMetadata, worldToIndexWSIMetadata, } from './wsiTransformUtils.js'; class WSIResolvedView extends ResolvedViewportView { canvasToWorld(canvasPos) { const indexPoint = canvasToIndexForWSI({ canvasHeight: this.state.canvasHeight, canvasPos, canvasWidth: this.state.canvasWidth, view: this.state.view, }); return indexToWorldWSIMetadata(this.state.metadata, indexPoint); } worldToCanvas(worldPos) { return indexToCanvasForWSI({ canvasHeight: this.state.canvasHeight, canvasWidth: this.state.canvasWidth, indexPos: worldToIndexWSIMetadata(this.state.metadata, worldPos), view: this.state.view, }); } getFrameOfReferenceUID() { return this.state.frameOfReferenceUID || undefined; } withZoom(zoom, canvasPoint) { const nextZoom = Math.max(zoom, 0.001); const nextResolution = this.getResolutionForZoom(nextZoom); if (!canvasPoint) { return this.cloneWithViewState({ ...this.state.viewState, resolution: nextResolution, zoom: nextZoom, }); } const indexPoint = this.canvasToIndex(canvasPoint); return this.cloneWithViewState({ ...this.state.viewState, centerIndex: this.getCenterIndexForCanvasPoint({ canvasPoint, indexPoint, resolution: nextResolution, }), resolution: nextResolution, zoom: nextZoom, }); } buildICamera() { const focalPoint = this.canvasToWorld([ this.state.canvasWidth / 2, this.state.canvasHeight / 2, ]); const xSpacing = this.state.metadata?.spacing?.[0] || 1; const resolution = this.getResolution(); return { parallelProjection: true, focalPoint, position: focalPoint, viewUp: [0, -1, 0], parallelScale: this.state.canvasHeight * resolution * xSpacing, viewPlaneNormal: [0, 0, 1], rotation: this.state.view.getRotation?.() || this.state.viewState.rotation || 0, }; } canvasToIndex(canvasPos) { const indexPoint = canvasToIndexForWSI({ canvasHeight: this.state.canvasHeight, canvasPos, canvasWidth: this.state.canvasWidth, view: this.state.view, }); return [indexPoint[0], indexPoint[1]]; } getResolution() { return (this.state.view.getResolution?.() || this.state.viewState.resolution || 1); } getResolutionForZoom(zoom) { const viewZoom = this.state.view.getZoom?.() || this.state.viewState.zoom || 1; return (this.state.view.getResolutionForZoom?.(zoom) ?? this.getResolution() / Math.pow(2, zoom - viewZoom)); } getCenterIndexForCanvasPoint(args) { const { canvasPoint, indexPoint, resolution } = args; const pixelRatio = typeof window === 'undefined' ? 1 : window.devicePixelRatio || 1; const halfCanvasX = Math.max(this.state.canvasWidth, 1) / 2; const halfCanvasY = Math.max(this.state.canvasHeight, 1) / 2; const deltaCanvasX = canvasPoint[0] * pixelRatio - halfCanvasX; const deltaCanvasY = canvasPoint[1] * pixelRatio - halfCanvasY; const rotation = this.state.view.getRotation?.() || this.state.viewState.rotation || 0; const cos = Math.cos(rotation); const sin = Math.sin(rotation); const rotatedDeltaX = cos * deltaCanvasX + sin * deltaCanvasY; const rotatedDeltaY = -sin * deltaCanvasX + cos * deltaCanvasY; return [ indexPoint[0] - rotatedDeltaX * resolution, indexPoint[1] + rotatedDeltaY * resolution, ]; } cloneWithViewState(viewState) { return new WSIResolvedView({ ...this.state, viewState, }); } } export default WSIResolvedView;