public static bool listedIdentifier(string identifier) { if (MaterialProperties.materials.Count < 1) { MaterialProperties.buildMaterialList(); } return(MaterialProperties.materials.ContainsKey(identifier)); }
public double reflection(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial) { if (previousMaterial.dominantOnLeave) { return(previousMaterial.enterReflection(trace, norm, this)); } return(this.enterReflection(trace, norm, previousMaterial)); }
private void setDefaults(Object3dCollection parent, MaterialProperties mp) { this.tag = this.GetType().ToString(); this.parseOrder = TraceJournal.Instance.rnd.NextDouble(); this.materialproperties = mp; this.parent = parent; if (this.hasParent()) { this.parent.addObject3d(this); } }
public static MaterialProperties FromIdentifier(string identifier) { if (MaterialProperties.materials.Count < 1) { MaterialProperties.buildMaterialList(); } Scientrace.MaterialProperties retmat = MaterialProperties.getMaterial(identifier); if (retmat == null) { throw new ArgumentException("MaterialProperties Identifier \"" + identifier + "\" is unknown."); } return(retmat); }
public static void buildMaterialList( ) { //For backwards compatibility: MaterialProperties.materials.Add("suncyclepmma", AltPMMAProperties.Instance); MaterialProperties.addMaterial(PMMAProperties.Instance); MaterialProperties.addMaterial(AltPMMAProperties.Instance); MaterialProperties.addMaterial(BlackBodySurface.Instance); MaterialProperties.addMaterial(AirProperties.Instance); MaterialProperties.addMaterial(PerfectMirror.Instance); MaterialProperties.addMaterial(GaAsSurface.Instance); MaterialProperties.addMaterial(SodaLimeGlassProperties.Instance); MaterialProperties.addMaterial(SchottBK7Properties.Instance); //MaterialProperties.materialstablebuilt = true; }
public Scientrace.Sphere parseXSphere(XElement xSphere) { if (xSphere.Name.ToString() != "Sphere") { throw new XMLException("Sphere does not match its name: " + xSphere.Name.ToString()); } double radius = this.X.getXDouble(xSphere, "Radius"); Scientrace.Location loc = this.X.getXLocation(xSphere, "Location"); // Replaced with below: Scientrace.MaterialProperties materialprops = this.getXMaterial(xSphere.Element("Material")); Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xSphere); Scientrace.Sphere tRetSphere = new Scientrace.Sphere(this.parentcollection, materialprops, loc, radius); tRetSphere.setRefAxis(this.X.getXNzVectorByName(xSphere, "RefVec", null)); return(tRetSphere); }
public Scientrace.RectangularPrism parseXRectangularPrism(XElement xrectprism) { //try { //Console.WriteLine("Adding Square Prism"); //check basic prerequisites if (xrectprism.Name.ToString() != "RectangularPrism") { throw new XMLException("RectangularPrism does not match its name: " + xrectprism.Name.ToString()); } Scientrace.Vector width = this.X.getXVectorByName(xrectprism, "Width"); Scientrace.Vector length = this.X.getXVectorByName(xrectprism, "Length"); Scientrace.Vector height = this.X.getXVectorByName(xrectprism, "Height"); if (width.length * length.length * height.length == 0) { Console.WriteLine("WARNING: Rectangular Prism " + xrectprism.Attribute("Tag").Value + " has no volume and will " + "therefor not be created."); return(null); } Scientrace.Location location = null; if (xrectprism.Element("Center") == null) { location = this.X.getXVectorByName(xrectprism, "Location").toLocation(); } else { location = (this.X.getXVectorByName(xrectprism, "Center") + (width * -0.5) + (length * -0.5) + (height * -0.5)) .toLocation(); } Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xrectprism); /* * string materialid = this.X.getXStringByAttribute(xrectprism,"Material"); * Scientrace.MaterialProperties material = Scientrace.MaterialProperties.FromIdentifier(materialid); */ //tryToNonzeroVector operations below are permitted since the prism has a volume as was tested above. Scientrace.RectangularPrism tretprism = new Scientrace.RectangularPrism(this.parentcollection, materialprops, location, width.tryToNonzeroVector(), height.tryToNonzeroVector(), length.tryToNonzeroVector()); this.addCommonObjectProperties(tretprism, xrectprism); return(tretprism); /* } catch(Exception e) {Console.WriteLine("Couldn't create RectangularPrism: "+this.X.getXString(xrectprism.Attribute("Tag"))); * throw(e); * }*/ }
/* replaced by ShadowScientrace factory * public Scientrace.DoubleConvexLens parseXDoubleConvexLens(XElement xLens) { * * if (xLens.Name.ToString() != "DoubleConvexLens") { * throw new XMLException("DoubleConvexLens does not match its name: "+xLens.Name.ToString()); * } * * Scientrace.MaterialProperties materialprops = this.getXMaterial(xLens.Element("Material")); * Scientrace.Location lensPlaneCenterLoc = this.X.getXLocation(xLens, "LensPlaneCenter"); * Scientrace.NonzeroVector lensPlaneNormal = this.X.getXNzVectorByName(xLens, "LensPlaneNormal"); * double r1 = this.X.getXDouble(xLens, "Radius1"); * double r2 = this.X.getXDouble(xLens, "Radius2"); * double lensDiameter = this.X.getXDouble(xLens, "LensDiameter"); * * Scientrace.DoubleConvexLens tRetLens = null; * * Scientrace.DoubleConvexLens.CreateWithLensDiameter( * this.parentcollection, materialprops, lensPlaneCenterLoc, lensPlaneNormal, * lensDiameter, r1, r2); * * return tRetLens; * } */ public Scientrace.PlanoConvexLens parseXPlanoConvexLens(XElement xLens) { if (xLens.Name.ToString() != "PlanoConvexLens") { throw new XMLException("PlanoConvexLens does not match its name: " + xLens.Name.ToString()); } // Replaced with below: Scientrace.MaterialProperties materialprops = this.getXMaterial(xLens.Element("Material")); Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xLens); Scientrace.Location lensFlatCenterLoc = this.X.getXLocation(xLens, "PlanoCenter");; Scientrace.NonzeroVector sphereRadiusVec = this.X.getXNzVectorByName(xLens, "SphereRadius"); double lensDiameter = this.X.getXDouble(xLens, "LensDiameter");; Scientrace.PlanoConvexLens tRetLens = null; Scientrace.PlanoConvexLens.CreateWithLensDiameter( this.parentcollection, materialprops, lensFlatCenterLoc, lensDiameter, sphereRadiusVec); return(tRetLens); }
public Scientrace.PlaneBorderEnclosedVolume parseXTruncatedPyramid(XElement xTruncatedPyramid) { // Replaced with below: Scientrace.MaterialProperties materialprops = this.getXMaterial(xToppedPyramid.Element("Material")); Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xTruncatedPyramid); if ((xTruncatedPyramid.Name.ToString() != "TruncatedPyramid") && (xTruncatedPyramid.Name.ToString() != "ToppedPyramid")) { throw new XMLException("TruncatedPyramid does not match its name: " + xTruncatedPyramid.Name.ToString()); } List <Scientrace.Location> front_corners = new List <Scientrace.Location>(); Scientrace.Vector loc_sum = new Scientrace.Vector(0, 0, 0); foreach (XElement xFrontCorner in xTruncatedPyramid.Elements("Corner")) { Scientrace.Location loc = this.X.getXLocation(xFrontCorner); front_corners.Add(loc); loc_sum = loc_sum + loc; } Scientrace.Vector loc_avg = loc_sum / front_corners.Count; Scientrace.Location virtual_top = this.X.getXLocation(xTruncatedPyramid, "VirtualTop"); // parsing topping plane data: XElement xTopPlane = xTruncatedPyramid.Element("TopPlane"); if (xTopPlane == null) { throw new XMLException("TopPlane element not found... " + xTruncatedPyramid.ToString()); } Scientrace.Location topPlaneLoc = this.X.getXLocation(xTopPlane, "Location"); Scientrace.NonzeroVector topPlaneNormal = this.X.getXNzVectorByName(xTopPlane, "Normal"); if (topPlaneNormal.dotProduct((topPlaneLoc - loc_avg)) > 0) { topPlaneNormal = topPlaneNormal.negative(); } Scientrace.PlaneBorder topping_plane = new Scientrace.PlaneBorder(topPlaneLoc, topPlaneNormal); Scientrace.PlaneBorderEnclosedVolume tRetTruncatedPyramid = Scientrace.PlaneBorderEnclosedVolume.createTruncatedPyramid(this.parentcollection, materialprops, front_corners, virtual_top, topping_plane); return(tRetTruncatedPyramid); }
public Object3dCollection[] division; //firsthalf, secondhalf; //public Scientrace.RectangularPrism dummyRect; /// <summary> /// The CircularFresnelPrism is developed specifically for the SunCycle system but can be used /// for different purposes. It generates a filled Object3dCollection with /// </summary> /// <param name="parent"> /// A <see cref="Object3d"/> /// </param> /// <param name="surroundingsproperties"> /// A <see cref="MaterialProperties"/> /// </param> /// <param name="loc"> /// A <see cref="Location"/> /// </param> /// <param name="surfacev1"> /// A <see cref="NonzeroVector"/> orthogonal to the prism-teeth "length"-direction. /// </param> /// <param name="surfacev2"> /// A <see cref="NonzeroVector"/> /// </param> /// <param name="surfacev3"> /// The Z axis </param> /// <param name="teethCount"> /// A int representing the number of teeth over the fresnel surface. /// </param> /// <param name="fresnelMaterial"> /// A <see cref="MaterialProperties"/> /// </param> public CircularFresnelPrism(Object3dCollection parent, MaterialProperties surroundingsproperties, Location loc, NonzeroVector surfacev1, NonzeroVector surfacev2, NonzeroVector zaxisheight, double largeAngle_rad, double shortAngle_rad, int teethCount, MaterialProperties fresnelMaterial) : base(parent, surroundingsproperties) { //check vectors try{ surfacev1.toUnitVector(); } catch { throw new ZeroNonzeroVectorException("Fresnel Prism surface 1 has length 0"); } try{ surfacev2.toUnitVector(); } catch { throw new ZeroNonzeroVectorException("Fresnel Prism surface 2 has length 0"); } try{ zaxisheight.toUnitVector(); } catch { throw new ZeroNonzeroVectorException("Z-axis height has length 0"); } //set attributes this.loc = loc; this.surfacev1 = surfacev1; this.surfacev2 = surfacev2; this.surfacev3 = zaxisheight; this.largeAngle = largeAngle_rad; this.relative_angle = Math.PI - (shortAngle_rad + largeAngle_rad); this.teethCount = teethCount; this.fresnelMaterial = fresnelMaterial; //create "divisions" that organises the Fresnel-zones in segments in order to boost performance. this.division = new Object3dCollection[this.divisioncount]; for (int idiv = 0; idiv < this.divisioncount; idiv++) { this.division[idiv] = new Object3dCollection(this, surroundingsproperties); this.division[idiv].virtualCollection = true; this.division[idiv].tag = "fresnel_div_" + idiv; } this.addElements(); this.dummyborder = new RectangularPrism(null, this.materialproperties, loc - (surfacev1 + surfacev2), surfacev1 * 2, surfacev2 * 2, surfacev3.normalized() * this.total_prism_height); }
public Scientrace.MaterialProperties getXMaterialForObject(XElement xmaterial) { ShadowClassConstruct scc = new ShadowClassConstruct(this.parentcollection); Scientrace.MaterialProperties matprop = scc.getXMaterial(xmaterial); return(matprop); /* * string materialid = this.X.getXStringByAttribute(xmaterial,"Class"); * if (Scientrace.MaterialProperties.listedIdentifier(materialid)) { * return Scientrace.MaterialProperties.FromIdentifier(materialid); * } * * switch (materialid) { * case "StaticNTransparant": //old type I once made... :S * case "StaticNTransparent": * double refindex = this.X.getXDouble(xmaterial, "RefractiveIndex"); * return new Scientrace.StaticNTransparentMaterial(refindex); * //break; * default: * throw new XMLException("Material Class ["+materialid+"] unknown"); * //break; * }*/ }
public Scientrace.ComplexBorderedVolume parsXBorderedVolume(XElement xBorVol) { // Replaced with below: Scientrace.MaterialProperties materialprops = this.getXMaterial(xBorVol.Element("Material")); Scientrace.MaterialProperties materialprops = this.getXMaterialForObject(xBorVol); if (xBorVol.Name.ToString() != "BorderedVolume") { throw new XMLException("BorderedVolume does not match its name: " + xBorVol.Name.ToString()); } List <List <Scientrace.PlaneBorder> > nestedBorders = new List <List <Scientrace.PlaneBorder> >(); foreach (XElement xSubVolume in xBorVol.Elements("SubVolume")) { List <Scientrace.PlaneBorder> tBorderList = new List <Scientrace.PlaneBorder>(); foreach (XElement xBorder in xSubVolume.Elements("Plane")) { if (xBorder.Element("Loc1") == null) // No LocSet? Defined by location and AllowedNormal { Scientrace.Location borderLoc = this.X.getXLocation(xBorder, "Location"); Scientrace.NonzeroVector borderAllowDir = this.X.getXNzVectorByName(xBorder, "AllowedNormal"); tBorderList.Add(new Scientrace.PlaneBorder(borderLoc, borderAllowDir)); } else // LocSet defined with 3 locations and an included-location to define the direction. { Scientrace.Location loc1 = this.X.getXLocation(xBorder, "Loc1"); Scientrace.Location loc2 = this.X.getXLocation(xBorder, "Loc2"); Scientrace.Location loc3 = this.X.getXLocation(xBorder, "Loc3"); Scientrace.Location includeLoc = this.X.getXLocation(xBorder, "IncludeLoc"); tBorderList.Add(Scientrace.PlaneBorder.createBetween3LocationsPointingTo(loc1, loc2, loc3, includeLoc)); } } nestedBorders.Add(tBorderList); } Scientrace.ComplexBorderedVolume tRetBoxVol = new Scientrace.ComplexBorderedVolume(this.parentcollection, materialprops, nestedBorders); return(tRetBoxVol); }
public Object3dEnvironment(MaterialProperties mp, double radius) : base(null, mp) { this.radius = radius; }
public virtual double enterReflection(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial) { double ti = trace.traceline.direction.angleWith(norm.negative()); double sti = Math.Sin(ti); double cti = Math.Cos(ti); /*debug Console.WriteLine("reflecting prev.: "+ previousObject.GetType()); Console.WriteLine("reflecting prev. material: "+ previousObject.materialproperties.GetType());*/ double n1 = previousMaterial.refractiveindex(trace); double n2 = this.refractiveindex(trace); //Fresnel Equations on a 50/50 distribution of parallel and perpendicular to the plane polarization double Rs = Math.Pow( ( (n1*cti) - (n2*Math.Sqrt(1.0 - Math.Pow((n1/n2)*sti,2.0))) ) / ( (n1*cti) + (n2*Math.Sqrt(1.0 - Math.Pow((n1/n2)*sti,2.0))) ) ,2.0); double Rp = Math.Pow( ( (n1*Math.Sqrt(1.0-Math.Pow((n1/n2)*sti,2.0))) - (n2*cti) ) / ( (n1*Math.Sqrt(1.0-Math.Pow((n1/n2)*sti,2.0))) + (n2*cti) ) ,2.0); double R = (Rs+Rp)/2.0; // Console.WriteLine("Reflection (n1/n2) = ("+n1+"/"+n2+") for angle "+ti+" is ("+Rs+"+"+Rp+")/2 ="+R); // Console.WriteLine("Reflection "+trace.traceline.direction.trico()+"->"+norm.trico()+" for angle "+ti+" is ("+Rs+"+"+Rp+")/2 ="+R); if (!((R>=0) && (R<1))) { Console.WriteLine("R==null("+R+", Rs:"+Rs+" Rp:"+Rp+" n1:"+n1+" n2:"+n2+" ti:"+ti+" rpnoem:"+ ((n1/n2)*sti)+") where "+this.ToString()+ " and "+previousMaterial.ToString()); } /*StackTrace stackTrace = new StackTrace(); MethodBase methodBase = stackTrace.GetFrame(1).GetMethod(); Console.WriteLine(methodBase.Name); // e.g. */ return R; }
/******************** INSTANCE METHODS *****************/ public virtual double absorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial) { if (previousMaterial.dominantOnLeave) return (previousMaterial.enterAbsorption(trace, norm, this)); return this.enterAbsorption(trace, norm, previousMaterial); }
//materials can transmit, reflect and absorp light. public virtual double enterAbsorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial) { return 0; }
public virtual double getLeaveAbsorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties nextMaterial) { throw new NotImplementedException("getLeaveAbsorption is not implemented for "+this.GetType().ToString()); }
public static void addMaterial(MaterialProperties mp) { MaterialProperties.materials.Add((mp.identifier()).ToLower(), mp); }
/// <summary> /// All Object3d instances should be created with an assigned parent, /// an ObjectCollection instance. Except for Environment instances which /// are "top level" collections. Their parent is automatically set "null". /// </summary> /// <param name="parent"> /// A <see cref="Object3d"/> /// </param> public Object3d(Object3dCollection parent, MaterialProperties mp) { this.setDefaults(parent, mp); }
/* /// <summary> /// If a collection contains a lot of objects, it might be usefull to specify a large border /// whithin they all should exist. This way the raytracer can check whether they all should /// be parsed individually in the first place or not. Leaving this object "null" it doesn't /// perform this check. Any type of object will do, including collections. Of course always /// keep in mind the only purpose is to gain performance. /// </summary> // public Object3d contentsWithinVirtualObject = null; MADE OBSOLETE BY DUMMYBORDER */ /// <summary> /// A collection of objects which will be iterated one by one when the collection is addressed. /// </summary> /// <param name="parent"> /// A <see cref="Object3dCollection"/>. There always has to be a parent collection in which /// an object (including objectcollections which are also objects as such) exists. The top /// collection (root) is the Object3dEnvironment collection. /// </param> /// <param name="mp"> /// A <see cref="MaterialProperties"/>. The surroundings in which the objects are situated? /// </param> public Object3dCollection(Object3dCollection parent, MaterialProperties mp) : base(parent, mp) { }
public virtual double enterReflection(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial) { double ti = trace.traceline.direction.angleWith(norm.negative()); double sti = Math.Sin(ti); double cti = Math.Cos(ti); /*debug Console.WriteLine("reflecting prev.: "+ previousObject.GetType()); Console.WriteLine("reflecting prev. material: "+ previousObject.materialproperties.GetType());*/ double n1 = previousMaterial.refractiveindex(trace); double n2 = this.refractiveindex(trace); //Fresnel Equations on a 50/50 distribution of parallel and perpendicular to the plane polarization double Rs = Math.Pow( ((n1 * cti) - (n2 * Math.Sqrt(1.0 - Math.Pow((n1 / n2) * sti, 2.0)))) / ((n1 * cti) + (n2 * Math.Sqrt(1.0 - Math.Pow((n1 / n2) * sti, 2.0)))) , 2.0); double Rp = Math.Pow( ((n1 * Math.Sqrt(1.0 - Math.Pow((n1 / n2) * sti, 2.0))) - (n2 * cti)) / ((n1 * Math.Sqrt(1.0 - Math.Pow((n1 / n2) * sti, 2.0))) + (n2 * cti)) , 2.0); double R = (Rs + Rp) / 2.0; // Console.WriteLine("Reflection (n1/n2) = ("+n1+"/"+n2+") for angle "+ti+" is ("+Rs+"+"+Rp+")/2 ="+R); // Console.WriteLine("Reflection "+trace.traceline.direction.trico()+"->"+norm.trico()+" for angle "+ti+" is ("+Rs+"+"+Rp+")/2 ="+R); if (!((R >= 0) && (R < 1))) { Console.WriteLine("R==null(" + R + ", Rs:" + Rs + " Rp:" + Rp + " n1:" + n1 + " n2:" + n2 + " ti:" + ti + " rpnoem:" + ((n1 / n2) * sti) + ") where " + this.ToString() + " and " + previousMaterial.ToString()); } /*StackTrace stackTrace = new StackTrace(); * MethodBase methodBase = stackTrace.GetFrame(1).GetMethod(); * Console.WriteLine(methodBase.Name); // e.g. */ return(R); }
public AttachedObject3dCollection(Object3dCollection parent, MaterialProperties mp) : base(parent, mp) { }
private void setDefaults(Object3dCollection parent, MaterialProperties mp) { this.tag = this.GetType().ToString(); this.parseOrder = TraceJournal.Instance.rnd.NextDouble(); this.materialproperties = mp; this.parent = parent; if (this.hasParent()) this.parent.addObject3d(this); }
//materials can transmit, reflect and absorp light. public virtual double enterAbsorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties previousMaterial) { return(0); }
public virtual double getLeaveAbsorption(Scientrace.Trace trace, Scientrace.UnitVector norm, MaterialProperties nextMaterial) { throw new NotImplementedException("getLeaveAbsorption is not implemented for " + this.GetType().ToString()); }