Skip to content

Commit

Permalink
Update protractor, add scoord conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmartel committed Jul 18, 2024
1 parent 8a82a0a commit da87501
Show file tree
Hide file tree
Showing 4 changed files with 536 additions and 163 deletions.
16 changes: 14 additions & 2 deletions src/dicom/dicomSpatialCoordinate.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Point2D} from '../math/point';
import {Line} from '../math/line';
import {Protractor} from '../math/protractor';
import {Circle} from '../math/circle';
import {Ellipse} from '../math/ellipse';
import {Rectangle} from '../math/rectangle';
Expand Down Expand Up @@ -122,7 +123,8 @@ export function getDicomSpatialCoordinateItem(scoord) {
/**
* Get a DICOM spatial coordinate (SCOORD) from a mathematical shape.
*
* @param {Point2D|Line|Circle|Ellipse|Rectangle} shape The math shape.
* @param {Point2D|Line|Protractor|Circle|Ellipse|Rectangle} shape
* The math shape.
* @returns {SpatialCoordinate} The DICOM scoord.
*/
export function getScoordFromShape(shape) {
Expand All @@ -142,6 +144,14 @@ export function getScoordFromShape(shape) {
shape.getEnd().getY().toString(),
];
scoord.graphicType = GraphicTypes.polyline;
} else if (shape instanceof Protractor) {
const pointList = shape.getPointList();
scoord.graphicData = [];
for (const point of pointList) {
scoord.graphicData.push(point.getX().toString());
scoord.graphicData.push(point.getY().toString());
}
scoord.graphicType = GraphicTypes.polyline;
} else if (shape instanceof Circle) {
const center = shape.getCenter();
const pointPerimeter = new Point2D(
Expand Down Expand Up @@ -192,7 +202,7 @@ export function getScoordFromShape(shape) {
* Get a mathematical shape from a DICOM spatial coordinate (SCOORD).
*
* @param {SpatialCoordinate} scoord The DICOM scoord.
* @returns {Point2D|Line|Circle|Ellipse|Rectangle} The math shape.
* @returns {Point2D|Line|Protractor|Circle|Ellipse|Rectangle} The math shape.
*/
export function getShapeFromScoord(scoord) {
// extract points
Expand Down Expand Up @@ -238,6 +248,8 @@ export function getShapeFromScoord(scoord) {
} else if (scoord.graphicType === GraphicTypes.polyline) {
if (points.length === 2) {
shape = new Line(points[0], points[1]);
} else if (points.length === 3) {
shape = new Protractor([points[0], points[1], points[2]]);
} else if (points.length === 4) {
shape = new Rectangle(points[0], points[2]);
}
Expand Down
6 changes: 6 additions & 0 deletions src/image/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {RulerFactory} from '../tools/ruler';
import {Line} from '../math/line';
import {ArrowFactory} from '../tools/arrow';
import {Point2D} from '../math/point';
import {ProtractorFactory} from '../tools/protractor';
import {Protractor} from '../math/protractor';

// doc imports
/* eslint-disable no-unused-vars */
Expand Down Expand Up @@ -186,6 +188,8 @@ export class Annotation {
fac = new ArrowFactory();
} else if (this.mathShape instanceof Line) {
fac = new RulerFactory();
} else if (this.mathShape instanceof Protractor) {
fac = new ProtractorFactory();
} else if (this.mathShape instanceof Circle) {
fac = new CircleFactory();
} else if (this.mathShape instanceof Ellipse) {
Expand All @@ -208,6 +212,8 @@ export class Annotation {
res = 'arrow';
} else if (this.mathShape instanceof Line) {
res = 'ruler';
} else if (this.mathShape instanceof Protractor) {
res = 'protractor';
} else if (this.mathShape instanceof Circle) {
res = 'circle';
} else if (this.mathShape instanceof Ellipse) {
Expand Down
86 changes: 86 additions & 0 deletions src/math/protractor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {Line, getAngle} from './line';
import {i18n} from '../utils/i18n';

// doc imports
/* eslint-disable no-unused-vars */
import {Point2D} from '../math/point';
import {ViewController} from '../app/viewController';
/* eslint-enable no-unused-vars */

/**
* Protractor shape: 3 points from which to calculate an angle.
*/
export class Protractor {

/**
* List of points.
*
* @type {Point2D[]}
*/
#pointArray;

/**
* @param {Point2D[]} pointArray The list of Point2D that make
* the protractor.
*/
constructor(pointArray) {
if (pointArray.length > 3) {
throw new Error('Too many points for a protractor');
}
this.#pointArray = pointArray.slice(0, 3);
}

/**
* Get the point list.
*
* @returns {Point2D[]} The list.
*/
getPointList() {
return this.#pointArray;
}

/**
* Get a point of the list.
*
* @param {number} index The index of the point
* to get (beware, no size check).
* @returns {Point2D|undefined} The Point2D at the given index.
*/
getPoint(index) {
return this.#pointArray[index];
}

/**
* Get the length of the path (should be 3).
*
* @returns {number} The length of the path.
*/
getLength() {
return this.#pointArray.length;
}

/**
* Quantify a path according to view information.
*
* @param {ViewController} _viewController The associated view controller.
* @param {string[]} _flags A list of stat values to calculate.
* @returns {object} A quantification object.
*/
quantify(_viewController, _flags) {
const quant = {};
if (this.#pointArray.length === 3) {
const line0 = new Line(this.#pointArray[0], this.#pointArray[1]);
const line1 = new Line(this.#pointArray[1], this.#pointArray[2]);
let angle = getAngle(line0, line1);
if (angle > 180) {
angle = 360 - angle;
}
quant.angle = {
value: angle,
unit: i18n.t('unit.degree')
};
}
return quant;
}

} // Protractor class
Loading

0 comments on commit da87501

Please sign in to comment.