/// <summary> /// Method that determines whether photon reflects or refracts across interface. When this /// method is called photon is sitting on boundary of region and CurrentRegionIndex is Index /// of region photon had been in. /// </summary> public void CrossRegionOrReflect() { double cosTheta = _tissue.GetAngleRelativeToBoundaryNormal(this); double nCurrent = _tissue.Regions[CurrentRegionIndex].RegionOP.N; int neighborIndex = _tissue.GetNeighborRegionIndex(this); double nNext = _tissue.Regions[neighborIndex].RegionOP.N; double coscrit; if (nCurrent > nNext) { coscrit = Math.Sqrt(1.0 - (nNext / nCurrent) * (nNext / nCurrent)); } else { coscrit = 0.0; } double probOfReflecting; double cosThetaSnell; // call Fresnel be default to have uZSnell set, used to be within else probOfReflecting = Optics.Fresnel(nCurrent, nNext, cosTheta, out cosThetaSnell); if (cosTheta <= coscrit) { probOfReflecting = 1.0; } //else // probOfReflecting = Optics.Fresnel(nCurrent, nNext, cosTheta, out cosThetaSnell); /* Decide whether or not photon goes to next region */ // perform first check so that rng not called on pseudo-collisions if ((probOfReflecting == 0.0) || (_rng.NextDouble() > probOfReflecting)) // transmitted { // if at border of system if (_tissue.OnDomainBoundary(this.DP.Position) && !_firstTimeEnteringDomain) { DP.StateFlag = DP.StateFlag.Add(_tissue.GetPhotonDataPointStateOnExit(DP.Position)); // adjust CAW weight for portion of track prior to exit if (Absorb == AbsorbContinuous) { AbsorbContinuous(); } CurrentRegionIndex = neighborIndex; //don't need to update these unless photon not dead upon exiting tissue //DP.Direction.Ux *= nCurrent / nNext; //DP.Direction.Uy *= nCurrent / nNext; //DP.Direction.Uz = uZSnell; } else // not on domain boundary, at internal interface or first time enter tissue, pass to next { CurrentRegionIndex = neighborIndex; DP.Direction = _tissue.GetRefractedDirection(DP.Position, DP.Direction, nCurrent, nNext, cosThetaSnell); if (_firstTimeEnteringDomain) { _firstTimeEnteringDomain = false; } } } else // don't cross, reflect { DP.Direction = _tissue.GetReflectedDirection(DP.Position, DP.Direction); // check if specular reflection if (_firstTimeEnteringDomain) { DP.StateFlag = DP.StateFlag.Add(PhotonStateType.PseudoSpecularTissueBoundary); } } }