/* Copyright (c) 2001-2015, David A. Clunie DBA Pixelmed Publishing. All rights reserved. */ package org.weasis.dicom.codec.geometry; import java.awt.geom.Point2D; import java.util.List; import javax.vecmath.Point3d; import javax.vecmath.Tuple3d; import javax.vecmath.Vector3d; /** * @author dclunie */ public class IntersectSlice extends LocalizerPoster { public IntersectSlice(Vector3d row, Vector3d column, Point3d tlhc, Tuple3d voxelSpacing, Tuple3d dimensions) { super(row, column, tlhc, voxelSpacing, dimensions); } public IntersectSlice(GeometryOfSlice geometry) { super(geometry); } private static boolean allTrue(boolean[] array) { boolean all = true; for (int i = 0; i < array.length; ++i) { if (!array[i]) { all = false; break; } } return all; } private static boolean oppositeEdges(boolean[] array) { return array[0] && array[2] || array[1] && array[3]; } private static boolean adjacentEdges(boolean[] array) { return array[0] && array[1] || array[1] && array[2] || array[2] && array[3] || array[3] && array[0]; } private static boolean[] classifyCornersOfRectangleIntoEdgesCrossingZPlane(Point3d[] corners) { int size = corners.length; boolean classification[] = new boolean[size]; for (int i = 0; i < size; ++i) { int next = (i == size - 1) ? 0 : i + 1; classification[i] = classifyCornersIntoEdgeCrossingZPlane(corners[i], corners[next]); } return classification; } @Override public List<Point2D.Double> getOutlineOnLocalizerForThisGeometry(Vector3d row, Vector3d column, Point3d tlhc, Tuple3d voxelSpacing, double sliceThickness, Tuple3d dimensions) { Point3d[] corners = getCornersOfSourceRectangleInSourceSpace(row, column, tlhc, voxelSpacing, dimensions); for (int i = 0; i < 4; ++i) { // We want to consider each edge of the source slice with respect to // the plane of the target localizer, so transform the source corners // into the target localizer space, and then see which edges cross // the Z plane of the localizer corners[i] = transformPointFromSourceSpaceIntoLocalizerSpace(corners[i]); // Now, points with a Z value of zero are in the plane of the localizer plane // Edges with one Z value +ve (or 0) and the other -ve (or 0) cross (or touch) the localizer plane // Edges with both Z values +ve or both -ve don't cross the localizer plane } boolean[] edges = classifyCornersOfRectangleIntoEdgesCrossingZPlane(corners); if (allTrue(edges)) { // "Source in exactly the same plane as the localizer return drawOutlineOnLocalizer(corners); // draw a rectangle } else if (oppositeEdges(edges)) { // draw line between where two edges cross (have zero Z value) return drawLinesBetweenAnyPointsWhichIntersectPlaneWhereZIsZero(corners); } else if (adjacentEdges(edges)) { // draw line between where two edges cross (have zero Z value) return drawLinesBetweenAnyPointsWhichIntersectPlaneWhereZIsZero(corners); } else { // No edges cross the localizer return null; } } }