} // 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 override Scientrace.VectorTransform getGridTransform(UnitVector nz) { NonzeroVector u, v, w; u = this.width; v = this.height; w = this.length; while (Math.Abs(nz.dotProduct(u.normalized())) > 0.99) { u = v; v = w; w = w.vectorDance().tryToUnitVector(); } while (Math.Abs(nz.dotProduct(v.normalized())) > 0.99) { v = w; w = w.vectorDance().tryToUnitVector(); } /*Console.WriteLine("NEW MAT:"+ * u.tricon()+ * v.tricon()+ * nz.tricon()); */ return(new Scientrace.VectorTransform(u, v, nz)); }
public string angleToRGB(Scientrace.Spot aCasualty, PhysicalObject3d physObj) { UnitVector inAngle = aCasualty.trace.traceline.direction; Scientrace.Parallelogram pg = physObj.getDistributionSurface(); Scientrace.NonzeroVector norm = physObj.getSurfaceNormal(); UnitVector y = pg.plane.v.toUnitVector(); UnitVector x = null; try { x = norm.crossProduct(y).tryToUnitVector(); } catch { throw new ZeroNonzeroVectorException("The vertical vector (plane.v) is parallel to the unit normal."); } double dx = x.dotProduct(inAngle); double dy = y.dotProduct(inAngle); double lengthFraction = Math.Sqrt((dx * dx) + (dy * dy)); //Console.WriteLine("Length: "+lengthFraction+ " vs: "+((x*dx)+(y*dy)).length); double angle = Math.Atan2(dy, dx); return(this.angleToHTML(angle, 2 * Math.Asin(lengthFraction) / Math.PI)); //physObj.getSurfaceNormal() //aCasualty.object3d. // throw new Exception("Not yet implemented"); }
/// <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); }
public override Scientrace.VectorTransform getGridTransform(UnitVector nz) { NonzeroVector u, v, w; u = this.width; v = this.height; w = this.length; while (Math.Abs(nz.dotProduct(u.normalized())) > 0.99) { u = v; v = w; w = w.vectorDance().tryToUnitVector(); } while (Math.Abs(nz.dotProduct(v.normalized())) > 0.99) { v = w; w = w.vectorDance().tryToUnitVector(); } /*Console.WriteLine("NEW MAT:"+ u.tricon()+ v.tricon()+ nz.tricon()); */ return new Scientrace.VectorTransform(u,v,nz); }