} // end func partialReflectRefract public void initCreatedRefractTrace(Trace refractTrace, UnitVector surfaceNormal, Scientrace.Object3d fromObject3d, Scientrace.Object3d toObject3d) { double oldrefindex = fromObject3d.materialproperties.refractiveindex(this); double newrefindex = toObject3d.materialproperties.refractiveindex(this); //for definitions on the parameters below, check fullInternalReflects function. UnitVector incoming_trace_direction = this.traceline.direction; if (incoming_trace_direction.dotProduct(surfaceNormal) > 0) { surfaceNormal = surfaceNormal.negative(); } Scientrace.UnitVector nnorm = surfaceNormal.negative(); Scientrace.Vector incoming_normal_projection = nnorm * (incoming_trace_direction.dotProduct(nnorm)); Vector L1 = incoming_trace_direction - incoming_normal_projection; double L2 = (oldrefindex / newrefindex) * L1.length; if (incoming_trace_direction == incoming_normal_projection) { //in case of normal incident light: do not refract. refractTrace.traceline.direction = incoming_trace_direction; return; } try { refractTrace.traceline.direction = ((nnorm * Math.Sqrt(1 - Math.Pow(L2, 2))) + (L1.tryToUnitVector() * L2)).tryToUnitVector(); } catch (ZeroNonzeroVectorException) { Console.WriteLine("WARNING: cannot define direction for refraction trace. Using surface normal instead. (L1: " + incoming_trace_direction.trico() + ", L2:" + incoming_normal_projection.trico() + ")."); refractTrace.traceline.direction = nnorm; } //end try/catch }
public void initCreatedRefractTrace(Trace refractTrace, UnitVector surfaceNormal, Scientrace.Object3d fromObject3d, Scientrace.Object3d toObject3d) { double oldrefindex = fromObject3d.materialproperties.refractiveindex(this); double newrefindex = toObject3d.materialproperties.refractiveindex(this); //for definitions on the parameters below, check fullInternalReflects function. UnitVector incoming_trace_direction = this.traceline.direction; if (incoming_trace_direction.dotProduct(surfaceNormal) > 0) { surfaceNormal = surfaceNormal.negative(); } Scientrace.UnitVector nnorm = surfaceNormal.negative(); Scientrace.Vector incoming_normal_projection = nnorm*(incoming_trace_direction.dotProduct(nnorm)); Vector L1 = incoming_trace_direction-incoming_normal_projection; double L2 = (oldrefindex/newrefindex)*L1.length; if (incoming_trace_direction == incoming_normal_projection) { //in case of normal incident light: do not refract. refractTrace.traceline.direction = incoming_trace_direction; return; } try { refractTrace.traceline.direction = ((nnorm*Math.Sqrt(1 - Math.Pow(L2,2))) +(L1.tryToUnitVector()*L2)).tryToUnitVector(); } catch (ZeroNonzeroVectorException) { Console.WriteLine("WARNING: cannot define direction for refraction trace. Using surface normal instead. (L1: "+incoming_trace_direction.trico()+", L2:"+incoming_normal_projection.trico()+")."); refractTrace.traceline.direction = nnorm; } //end try/catch }
/// <summary> /// Fulls the internal reflects. /// </summary> /// <returns> /// True if full internal reflection occurs. Returns false in case of refraction and partial reflection /// </returns> /// <param name='incoming_trace_direction'> /// incoming_trace_direction is the vector of the trace passing the surface /// </param> public bool fullInternalReflects(UnitVector surfaceNormal, Scientrace.Object3d fromObject3d, Scientrace.Object3d toObject3d) { double oldrefindex = fromObject3d.materialproperties.refractiveindex(this); double newrefindex = toObject3d.materialproperties.refractiveindex(this); UnitVector incoming_trace_direction = this.traceline.direction; // make sure the surfaceNormal is directed towards the incoming beam (so in the opposite direction) if (incoming_trace_direction.dotProduct(surfaceNormal) > 0) { surfaceNormal = surfaceNormal.negative(); } // nnorm is surface normale directed into the *new* surface, so *along* the incoming beam Scientrace.UnitVector nnorm = surfaceNormal.negative(); // incoming_normal_projection is the projection of incoming_trace_direction at the (n)norm Scientrace.Vector incoming_normal_projection = nnorm*(incoming_trace_direction.dotProduct(nnorm)); // L1 and L2 are defined as on figure 15 / page 20 from the "Optical simulation of the SunCycle concentrator using Scientrace (J. Bos-Coenraad 2013) Vector L1 = incoming_trace_direction-incoming_normal_projection; double L2 = (oldrefindex/newrefindex)*L1.length; // If L2 is larger than 1, full internal reflection takes place. return (L2 > 1); }
/// <summary> /// Fulls the internal reflects. /// </summary> /// <returns> /// True if full internal reflection occurs. Returns false in case of refraction and partial reflection /// </returns> /// <param name='incoming_trace_direction'> /// incoming_trace_direction is the vector of the trace passing the surface /// </param> public bool fullInternalReflects(UnitVector surfaceNormal, Scientrace.Object3d fromObject3d, Scientrace.Object3d toObject3d) { double oldrefindex = fromObject3d.materialproperties.refractiveindex(this); double newrefindex = toObject3d.materialproperties.refractiveindex(this); UnitVector incoming_trace_direction = this.traceline.direction; // make sure the surfaceNormal is directed towards the incoming beam (so in the opposite direction) if (incoming_trace_direction.dotProduct(surfaceNormal) > 0) { surfaceNormal = surfaceNormal.negative(); } // nnorm is surface normale directed into the *new* surface, so *along* the incoming beam Scientrace.UnitVector nnorm = surfaceNormal.negative(); // incoming_normal_projection is the projection of incoming_trace_direction at the (n)norm Scientrace.Vector incoming_normal_projection = nnorm * (incoming_trace_direction.dotProduct(nnorm)); // L1 and L2 are defined as on figure 15 / page 20 from the "Optical simulation of the SunCycle concentrator using Scientrace (J. Bos-Coenraad 2013) Vector L1 = incoming_trace_direction - incoming_normal_projection; double L2 = (oldrefindex / newrefindex) * L1.length; // If L2 is larger than 1, full internal reflection takes place. return(L2 > 1); }