public double[] ProjectedPointAtIsocenterPlaneInUCS(double[] pointPCS, double SAD = 1000)
        {
            double[] sourceUCS = new double[3] {
                0.0, -SAD, 0.0
            };
            double[] pointUCS = new double[3] {
                0.0, 0.0, 0.0
            };
            CoordinateTransform3D.PlanningToUnitCoordinate(Isocenter,
                                                           GantryAngle, CollimatorAngle, CouchAngle,
                                                           pointPCS, pointUCS);

            double[] sourceToPointUCS = new double[3] {
                pointUCS[0] - sourceUCS[0], pointUCS[1] - sourceUCS[1], pointUCS[2] - sourceUCS[2]
            };

            if (sourceToPointUCS[1] < Double.Epsilon)
            {
                throw new InvalidOperationException("pointPCS is on or above the source plane");
            }

            double sf = SAD / Math.Abs(sourceToPointUCS[1]);

            double[] sourceToPointAtIcpUCS = new double[3] {
                sf *sourceToPointUCS[0], sf *sourceToPointUCS[1], sf *sourceToPointUCS[2]
            };

            double[] projectedPointAtIcpUCS = new double[3] {
                sourceUCS[0] + sourceToPointAtIcpUCS[0],
                sourceUCS[1] + sourceToPointAtIcpUCS[1],
                sourceUCS[2] + sourceToPointAtIcpUCS[2]
            };

            return(projectedPointAtIcpUCS);
        }
        /// <summary>
        /// Transform Planning coordinate to Unit coordinate
        /// </summary>
        /// <param name="planningCoordinate"> Planning coordinate to transform </param>
        /// <param name="unitCoordinate"> Transformed Unit coordinate </param>
        public void PCStoUCS(double[] planningCoordinate, double[] unitCoordinate)
        {
            CoordinateTransform3D.PlanningToUnitCoordinate(Isocenter,
                                                           GantryAngle, CollimatorAngle, CouchAngle,
                                                           planningCoordinate, unitCoordinate);

            return;
        }
        /// <summary>
        /// Constructor for BeamGeometry
        /// </summary>
        /// <param name="gantryAngle"> Gantry angle in degree </param>
        /// <param name="collimatorAngle"> Collimator angle in degree </param>
        /// <param name="couchAngle"> Couch angle in radian </param>
        /// <param name="isocenter"> Isocenter coordinate in the planning coordinate system in mm </param>
        /// <para name="patientOrientation"> Enum for patient orientation </para>
        public BeamGeometry(double gantryAngle, double collimatorAngle,
                            double couchAngle, double[] isocenter,
                            PatientOrientation patientOrientation = PatientOrientation.NoOrientation)
        {
            this.GantryAngle     = gantryAngle;
            this.CollimatorAngle = collimatorAngle;
            this.CouchAngle      = couchAngle;
            for (int i = 0; i < 3; i++)
            {
                this.Isocenter[i] = isocenter[i];
            }

            CoordinateTransform3D.SourceCoordinateInPlanningCoordinate(
                SourcePosition, isocenter, gantryAngle, collimatorAngle, couchAngle, SourceToAxisDistance);
        }
 public void UpdateSourcePosition()
 {
     CoordinateTransform3D.SourceCoordinateInPlanningCoordinate(
         SourcePosition, Isocenter, GantryAngle, CollimatorAngle, CouchAngle, SourceToAxisDistance);
 }