All 3D calculations in DicomObjects are almost entirely in “real world” coordinated (patient X,Y,Z in mm). We have implemented a few dedicated methods to help you manipulate your 3D object or the ones that are displayed. This includes the DicomImage.ImagePlane() (DicomImage.Projection.Plane in COM) which returns an Image’s plane in Plane3D form that can be used for other calculation (in real world units again), say the intersection of two Image planes, or to offset one of them by the slab thickness and to calculate that intersection, etc.

All calculations are done in real world 3D space (for consistency and simplicity) and then any point (the result) can be translated to Viewer/screen space using Image.WorldToScreen() method.  Once you have them in screen units, you can manipulate it in any way you like, such as adding perpendicular end-markers or other precise adjustments that you wish to have.

As an example, given below is a C# code snippet that we use to add reference lines from “RefImage” onto an DicomImage :

Plane3D? p1 = Image.ImagePlane(Image.Frame);
Plane3D? p2 = RefImage.ImagePlane(RefImage.Frame);

if (!p1.HasValue || !p2.HasValue)
    break; // parallel - can't draw

Line3D? L = Plane3D.PlaneIntersection(p1.Value, p2.Value);
if (!L.HasValue)
    break; // don't intersect

// Now we have L in "real world" units

// pick points on line - go to "infinite" length
Point3D q1 = L.Value.Anchor + L.Value.Direction * 10000;
Point3D q2 = L.Value.Anchor - L.Value.Direction * 10000;

// project onto screen plane
PointF ScreenPoint1 = Image.WorldToScreen(q1, size);
PointF ScreenPoint2 = Image.WorldToScreen(q2, size);