Exemple #1
0
        /// <summary>
        /// method to determine if photon ray (or track) will intersect boundary of cylinder
        /// equations to determine intersection are derived by parameterizing ray from p1 to p2
        /// as p2=p1+[dx dy dz]t t in [0,1] where dx=p2.x-p1.x dy=p2.y-p1.y dz=p2.z-p2.z
        /// and substituting into ellipsoid equations and solving quadratic in t, i.e. t1, t2
        /// t1,t2 less than 0 or t1,t2 greater than 1 => no intersection
        /// 0 less than t1 less than 1 => one intersection
        /// 0 less than t2 less than 1 => one intersections, if above line true too => two intersections
        /// </summary>
        /// <param name="photon">photon position, direction, etc.</param>
        /// <param name="distanceToBoundary">return: distance to boundary</param>
        /// <returns>boolean</returns>
        public bool RayIntersectBoundary(Photon photon, out double distanceToBoundary)
        {
            distanceToBoundary = double.PositiveInfinity;
            _onBoundary        = false; // reset _onBoundary
            double root = 0;
            var    dp   = photon.DP;
            var    p1   = dp.Position;
            var    d1   = dp.Direction;

            // determine location of end of ray
            var p2 = new Position(p1.X + d1.Ux * photon.S,
                                  p1.Y + d1.Uy * photon.S,
                                  p1.Z + d1.Uz * photon.S);

            bool oneIn = this.ContainsPosition(p1);
            bool twoIn = this.ContainsPosition(p2);

            //if ((Math.Abs(p1.X)<2)&& one_in)
            //{
            //    Console.WriteLine(String.Format("p1.x,y,z={0:F}, {1:F}, {2:F}, in={3}",p1.X,p1.Y,p1.Z,one_in));
            //    Console.WriteLine("****");
            //}

            // check if ray within cylinder
            if ((oneIn || _onBoundary) && twoIn)
            {
                return(false);
            }
            _onBoundary = false; // reset flag

            return(CylinderTissueRegionToolbox.RayIntersectInfiniteCylinder(p1, p2, oneIn,
                                                                            CylinderTissueRegionAxisType.Y, Center, Radius,
                                                                            out distanceToBoundary));
        }
Exemple #2
0
        /// <summary>
        /// method to determine if photon ray (or track) will intersect boundary of cylinder
        /// without caps
        /// </summary>
        /// <param name="photon">photon position, direction, etc.</param>
        /// <param name="distanceToBoundary">distance to boundary</param>
        /// <returns>boolean</returns>
        public bool RayIntersectBoundary(Photon photon, out double distanceToBoundary)
        {
            distanceToBoundary = double.PositiveInfinity;
            _onBoundary        = false; // reset _onBoundary
            double root = 0;
            var    dp   = photon.DP;
            var    p1   = dp.Position;
            var    d1   = dp.Direction;

            // determine location of end of ray
            var p2 = new Position(p1.X + d1.Ux * photon.S,
                                  p1.Y + d1.Uy * photon.S,
                                  p1.Z + d1.Uz * photon.S);

            bool oneIn = this.ContainsPosition(p1);
            bool twoIn = this.ContainsPosition(p2);

            // check if ray within cylinder
            if ((oneIn || _onBoundary) && twoIn)
            {
                return(false);
            }
            _onBoundary = false; // reset flag

            double distanceToSides = double.PositiveInfinity;
            // first check if intersect with infinite cylinder
            var intersectSides = (CylinderTissueRegionToolbox.RayIntersectInfiniteCylinder(
                                      p1, p2, oneIn, CylinderTissueRegionAxisType.Z, Center, Radius, out distanceToSides));

            if (intersectSides)
            {
                distanceToBoundary = distanceToSides;
                return(true);
            }

            //distanceToBottomLayer = double.PositiveInfinity;
            return(false);
        }
        /// <summary>
        /// Method to determine if photon ray (or track) will intersect boundary of cylinder
        /// equations to determine intersection are derived by parameterizing ray from p1 to p2
        /// as p2=p1+[dx dy dz]t t in [0,1] where dx=p2.x-p1.x dy=p2.y-p1.y dz=p2.z-p2.z
        /// and substituting into ellipsoid equations and solving quadratic in t, i.e. t1, t2
        /// t1,t2<0 or t1,t2>1 => no intersection
        /// 0<t1<1 => one intersection
        /// 0<t2<1 => one intersections, if above line true too => two intersections
        /// Equations obtained from pdf at https://mrl.nyu.edu/~dzorin/rendering/lectures/lecture3/lecture3-6pp.pdf
        /// and modified to assume cylinder finite along z-axis with caps in x-y planes.
        /// Note: can't vouch for this code yet, especially if photon intersects sides AND cap
        /// </summary>
        /// <param name="photon">photon position, direction, etc.</param>
        /// <param name="distanceToBoundary">distance to boundary</param>
        /// <returns>boolean</returns>
        public bool RayIntersectBoundary(Photon photon, out double distanceToBoundary)
        {
            distanceToBoundary = double.PositiveInfinity;
            _onBoundary        = false; // reset _onBoundary
            double root = 0;
            var    dp   = photon.DP;
            var    p1   = dp.Position;
            var    d1   = dp.Direction;

            // determine location of end of ray
            var p2 = new Position(p1.X + d1.Ux * photon.S,
                                  p1.Y + d1.Uy * photon.S,
                                  p1.Z + d1.Uz * photon.S);

            bool oneIn = this.ContainsPosition(p1);
            bool twoIn = this.ContainsPosition(p2);

            // check if ray within cylinder
            if ((oneIn || _onBoundary) && twoIn)
            {
                return(false);
            }
            _onBoundary = false; // reset flag

            double distanceToSides = double.PositiveInfinity;
            // first check if intersect with infinite cylinder
            var intersectSides = (CylinderTissueRegionToolbox.RayIntersectInfiniteCylinder(p1, p2, oneIn,
                                                                                           CylinderTissueRegionAxisType.Z, Center, Radius,
                                                                                           out distanceToSides));
            // then check if intersect caps, create three tissue layers 1) above cylinder, 2) cylinder, 3) below
            double distanceToTopLayer = double.PositiveInfinity;
            var    topLayer           = new LayerTissueRegion(
                new DoubleRange(0, Center.Z - (Height / 2)),
                new OpticalProperties()); // doesn't matter what OPs are
            var    intersectTopLayer  = topLayer.RayIntersectBoundary(photon, out distanceToTopLayer);
            double distanceToCapLayer = double.PositiveInfinity;
            var    enclosingLayer     =
                new LayerTissueRegion(
                    new DoubleRange(Center.Z - (Height / 2), Center.Z + (Height / 2)),
                    new OpticalProperties());
            var    intersectCapLayer     = enclosingLayer.RayIntersectBoundary(photon, out distanceToCapLayer);
            double distanceToBottomLayer = double.PositiveInfinity;
            var    bottomLayer           = new LayerTissueRegion(
                new DoubleRange(Center.Z + (Height / 2), double.PositiveInfinity),
                new OpticalProperties()); // doesn't matter what OPs are
            var    intersectBottomLayer = bottomLayer.RayIntersectBoundary(photon, out distanceToBottomLayer);
            var    hitCaps       = false;
            double distanceToCap = double.PositiveInfinity;

            if (intersectTopLayer || intersectCapLayer || intersectBottomLayer)
            {
                distanceToCap = Math.Min(distanceToTopLayer, Math.Min(distanceToCapLayer, distanceToBottomLayer));
                double xto = p1.X + distanceToCap * d1.Ux;
                double yto = p1.Y + distanceToCap * d1.Uy;
                double zto = p1.Z + distanceToCap * d1.Uz;
                if ((Math.Abs(zto - (Center.Z + (Height / 2))) < 1e-10 ||
                     Math.Abs(zto - (Center.Z - (Height / 2))) < 1e-10) &&
                    Math.Sqrt(xto * xto + yto * yto) < Radius)
                {
                    hitCaps = true;
                }
            }
            if (hitCaps && distanceToCap < distanceToSides)
            {
                distanceToBoundary = distanceToCap;
                return(true);
            }

            if (intersectSides && distanceToSides < distanceToCapLayer)
            {
                distanceToBoundary = distanceToSides;
                return(true);
            }

            distanceToBottomLayer = double.PositiveInfinity;
            return(false);
        }