/// <summary> /// Creates a line starting at the projection of this.loc on the intersection between this and another Plane. /// The direction of the line is that of the crossproduct of this.normal and anotherPlane.normal. /// </summary> /// <returns>A line along the intersection of this and anotherPlane, returns "null" if two planes are significantly parallel</returns> /// <param name="anotherPlane">A plane to calculate the intersection with</param> public Scientrace.Line getIntersectionLineWith(Scientrace.Plane anotherPlane) { Scientrace.UnitVector n1, n2; n1 = this.getNorm(); n2 = anotherPlane.getNorm(); Vector tw = n1.crossProduct(n2); if (tw.length < MainClass.SIGNIFICANTLY_SMALL) { //Console.WriteLine("WARNING: two planes do not intersect since they are parallel."); return(null); } UnitVector intersection_direction = tw.tryToUnitVector(); Vector tl1 = n1.crossProduct(intersection_direction); if (tl1.length == 0) { throw new Exception("Plane.getIntersectionLineWith/l1.length can never be zero. If this happens, notify the [email protected] about this..." + this.ToString() + anotherPlane.ToString()); } // l1 lies in "this" plane, and is orthogonal to the intersectionline-direction UnitVector l1 = tl1.tryToUnitVector(); // where l1, starting at this.loc, meets anotherPlane we found a location on the intersectionline. Scientrace.Location retLoc = anotherPlane.lineThroughPlane(new Line(this.loc, l1)); if (retLoc == null) { Console.WriteLine("WARNING: retLoc == null; l1: " + l1.ToString() + " ; anotherPlane:" + anotherPlane.getNorm().ToString()); return(null); } return(new Line(retLoc, intersection_direction)); }
public Scientrace.FlatShape2d baseIntersectionShape(double x, double y) { //return new Scientrace.FlatShape2d(new Plane(new Location(0,0,0), NonzeroVector.x1vector().negative(), NonzeroVector.z1vector())); Scientrace.Plane refplane = new Scientrace.Plane(new Scientrace.Location(x, y, this.c * Math.Pow(x, 2) * Math.Pow(y, 2)), new Scientrace.UnitVector(1, 0, 2 * c * x), new Scientrace.UnitVector(0, 1, 2 * c * y)); //Console.WriteLine("Mirror plane ("+x+", "+y+") equals: "+refplane.getNorm().trico()); return(new Scientrace.FlatShape2d(refplane)); }
public PlaneBorder(Scientrace.Location loc, Scientrace.NonzeroVector allowedDirectionSurfaceNormal) { this.loc = loc; this.allowedDirNormal = allowedDirectionSurfaceNormal; this.radius = allowedDirectionSurfaceNormal.length; this.allowedDirNormal.fillOrtogonalVectors(ref this.planeBaseVec1, ref this.planeBaseVec2); this.trf = this.createNewTransform(); this.tPlane = new Scientrace.Plane(this.loc, this.planeBaseVec1, this.planeBaseVec2); }
/* LINEAR MODIFIER METHODS >>> */ public Scientrace.Plane linearModify(Scientrace.Plane aPlane) { Scientrace.NonzeroVector aSurfaceNormal = aPlane.getNorm(); Scientrace.NonzeroVector newNormal = this.modify(aSurfaceNormal, this.random_modification_select ? this.getRandomNodeNumber() : this.getNextNodeNumber(), this.modify_traces_count); return(Scientrace.Plane.newPlaneOrthogonalTo(aPlane.loc, newNormal, aPlane.u, aPlane.v)); }
public Line reflectLine(Scientrace.Line line, Scientrace.Plane plane) { Scientrace.UnitVector norm = plane.getNorm(); /*ADDED and removed 20131030 make surface normal in direction of incoming beam * if (line.direction.dotProduct(norm) > 0) { * norm.negated(); * }*/ return(this.reflectLineAbout(line, norm)); }
public void setRefAxis(Scientrace.NonzeroVector refVec) { if (refVec == null) { return; } this.refVecZ = refVec.toUnitVector(); Scientrace.Plane tPlane = Plane.newPlaneOrthogonalTo(new Scientrace.Location(0, 0, 0), refVec); this.refVecX = tPlane.u.toUnitVector(); this.refVecY = tPlane.v.toUnitVector(); }
public SpiralLightSource(Scientrace.Object3dEnvironment env, Scientrace.Location center, Scientrace.UnitVector direction, Scientrace.Plane plane, int linecount, double radius, double loops, double distance, LightSpectrum spectrum) : base(env) { /*Scientrace.UniformTraceModifier utm = * //new UniformTraceModifier(DistributionPattern.PeriodicSingleCircle, SpatialDistribution.UniformAngles); * new UniformTraceModifier(DistributionPattern.SquareGrid, SpatialDistribution.UniformProjections); * utm.add_self = false; * utm.setMaxAngleDeg(0.5); * utm.modify_traces_count = 16; * utm.randomSeed = 1; * this.modifiers.Add(utm); */ //this.init_findmultip(env, center, direction, plane, linecount, radius, loops, spectrum); this.paramInit(center, direction, plane, linecount, radius, loops, distance); }
public void paramInit(Scientrace.Location center, Scientrace.UnitVector direction, Scientrace.Plane plane, int linecount, double radius, double loops, double distance) { this.loops = loops; this.radius = radius; this.center = center; //direction had been commented out. WHY? Re-enabled. this.direction = direction; this.spiral_plane = plane; this.tag = String.Format("{0:0.###}", loops) + "LoopSpiral"; this.distance = distance; //added later: this.linecount = linecount; //and removed again: //this.spectrum = spectrum; }
public override string exportX3D(Scientrace.Object3dEnvironment env) { //TODO: try to transform to indexedlineset Scientrace.Vector a, b, c, d, e, f, g, h; a = this.width; //front circle edges b = this.height; c = this.width.negative(); d = this.height.negative(); e = this.length + this.width; //back triangle f = this.length + this.height; g = this.length - this.width; h = this.length - this.height; //circle front //circle back (translated out of the "loc" starting point) //also end ratation transform. The connecting lines don't need that. //lineset for connecting lines to make the cylinder shape visible //connecting circles Scientrace.Plane circleplane = new Scientrace.Plane(new Scientrace.Location(0, 0, 0), width, height); return("<!-- Start CircularPrism instance -->\n<Transform translation='" + this.loc.trico() + "'>" + circleplane.x3dRotationTransform() + "<Shape>" + "<Circle2D radius='" + this.width.length + "' containerField='geometry'/>" + "</Shape></Transform>" + "<Transform translation='" + this.length.trico() + "'>" + circleplane.x3dRotationTransform() + "<Shape><Circle2D radius='" + this.width.length + "' containerField='geometry'/>" + "</Shape>" + "</Transform>" + "</Transform>" + "<Shape>" + "<LineSet vertexCount='2 2 2 2'>" + "<Coordinate point='" + a.tricon() + e.tricon() + b.tricon() + f.tricon() + c.tricon() + g.tricon() + d.tricon() + h.tricon() + "'/>" + " </LineSet> </Shape> </Transform>\n<!-- End CircularPrism instance -->"); // <Color color='1 0 0 1 0.5 0 1 1 0 0 1 0 1 0 0 0 0 1 0.8 0 0.8 0.3 0 0.3 1 1 1 0 0 1 1 0 0 0 0 1 1 0.5 0 0.8 0 0.8 1 1 0 0.3 0 0.3 0 1 0 1 1 1'/> }
public RandomCircleLightSource(Scientrace.Object3dEnvironment env, Scientrace.Location center, Scientrace.UnitVector direction, Scientrace.Plane plane, double radius, int linecount, LightSpectrum spectrum) : base(env) { //this.direction = direction; Random randNum = new Random(); Scientrace.UnitVector urange, vrange; double r1, r2; urange = plane.u.toUnitVector(); vrange = plane.v.toUnitVector(); Scientrace.Line line; for (int iline = 0; iline < linecount; iline++) { //Scientrace.Line line = new Scientrace.Line(loc+(urange*randNum.NextDouble()+(vrange*randNum.NextDouble())).toLocation(), direction); r1 = 1 - randNum.NextDouble() * 2; r2 = 1 - randNum.NextDouble() * 2; if (Math.Pow(r1, 2) + Math.Pow(r2, 2) < 1) { line = new Scientrace.Line(center + ((urange * r1 * radius) + (vrange * r2 * radius)).toLocation(), direction); } else { iline--; continue; } //this.traces.Add(new Scientrace.Trace(wavelength*0.6, this, line, env)); //this.traces.Add(new Scientrace.Trace(wavelength*0.8, this, line, env)); //double wavelength = wlmin+(randNum.NextDouble()*(wlmax-wlmin)); double wavelength = spectrum.wl(iline); double intensity = spectrum.it(iline); Console.WriteLine("Warning: ParallelRandomCylindricalLightSource does not use modulo yet"); this.addTrace(new Scientrace.Trace(wavelength, this, line, env, intensity, intensity)); //this.traces.Add(new Scientrace.Trace(wavelength*1.2, this, line, env)); //this.traces.Add(new Scientrace.Trace(wavelength*1.4, this, line, env)); } }
public override string exportX3D(Scientrace.Object3dEnvironment env) { //TODO: try to transform to indexedlineset Scientrace.Vector a, b, c, d, e, f, g, h; a = this.width; //front circle edges b = this.height; c = this.width.negative(); d = this.height.negative(); e = this.length+this.width; //back triangle f = this.length+this.height; g = this.length-this.width; h = this.length-this.height; //circle front //circle back (translated out of the "loc" starting point) //also end ratation transform. The connecting lines don't need that. //lineset for connecting lines to make the cylinder shape visible //connecting circles Scientrace.Plane circleplane = new Scientrace.Plane(new Scientrace.Location(0,0,0), width, height); return "<!-- Start CircularPrism instance -->\n<Transform translation='"+this.loc.trico()+"'>"+circleplane.x3dRotationTransform()+ "<Shape>" + "<Circle2D radius='"+this.width.length+"' containerField='geometry'/>" + "</Shape></Transform>"+ "<Transform translation='"+this.length.trico()+"'>"+circleplane.x3dRotationTransform()+ "<Shape><Circle2D radius='"+this.width.length+"' containerField='geometry'/>" + "</Shape>" + "</Transform>" + "</Transform>"+"<Shape>" + "<LineSet vertexCount='2 2 2 2'>" + "<Coordinate point='"+ a.tricon()+e.tricon()+b.tricon()+f.tricon()+c.tricon()+g.tricon()+d.tricon()+h.tricon()+"'/>" + " </LineSet> </Shape> </Transform>\n<!-- End CircularPrism instance -->"; // <Color color='1 0 0 1 0.5 0 1 1 0 0 1 0 1 0 0 0 0 1 0.8 0 0.8 0.3 0 0.3 1 1 1 0 0 1 1 0 0 0 0 1 1 0.5 0 0.8 0 0.8 1 1 0 0.3 0 0.3 0 1 0 1 1 1'/> }
public RandomCircleLightSource(ShadowScientrace.ShadowLightSource shadowObject) : base(shadowObject) { int?random_seed = shadowObject.getNInt("random_seed"); Scientrace.Location location = shadowObject.getLocation("location"); //corner Scientrace.UnitVector direction = shadowObject.getUnitVector("direction"); Scientrace.UnitVector normal = shadowObject.getUnitVector("normal"); // if normal is not defined, use the beam direction as the surface normal. if (normal == null) { normal = direction; } int ray_count = shadowObject.getInt("ray_count"); //linecount, this.distance = shadowObject.getDouble("distance", 0); //distance, //This line has been moved to the LightSource parent shadowconstructor //Scientrace.LightSpectrum spectrum = (Scientrace.LightSpectrum)shadowObject.getObject("spectrum"); //spectrum double radius = shadowObject.getDouble("radius"); //urange, Random randNum; if (random_seed == null || random_seed == -1) { randNum = new Random(); } else { randNum = new Random((int)random_seed); } Scientrace.Plane plane = Scientrace.Plane.newPlaneOrthogonalTo(location, normal); Scientrace.UnitVector urange, vrange; double r1, r2; urange = plane.u.toUnitVector(); vrange = plane.v.toUnitVector(); Scientrace.Line line; for (int iline = 0; iline < ray_count; iline++) { r1 = 1 - randNum.NextDouble() * 2; r2 = 1 - randNum.NextDouble() * 2; if (Math.Pow(r1, 2) + Math.Pow(r2, 2) < 1) { line = new Scientrace.Line(location + ((urange * r1 * radius) + (vrange * r2 * radius)).toLocation(), direction); // THIS IS BEING DONE BY THE PARENT LIGHTSOURCE CLASS ALREADY: line.startingpoint = line.startingpoint - (direction.toLocation()*distance); } else { iline--; continue; } double wavelength = spectrum.wl(iline); double intensity = spectrum.it(iline); Scientrace.Trace newtrace = new Scientrace.Trace(wavelength, this, line, env, intensity, intensity); newtrace.traceid = "RS" + (random_seed == null?"r":random_seed.ToString()) + "-" + iline; this.addTrace(newtrace); } }
public FlatShape2d(Scientrace.Location loc, Scientrace.NonzeroVector u, Scientrace.NonzeroVector v) { this.plane = new Plane(loc, u, v); }
public FlatShape2d(Scientrace.Plane aPlane) { this.plane = aPlane; }
public FlatShape2d(FlatShape2d copyFlatShape2d) { this.plane = new Scientrace.Plane(copyFlatShape2d.plane); }
public void setLightSourceConstructorParams(ShadowScientrace.ShadowLightSource shadowLS, XElement xel) { // STRUCTURE /* "dictionary name of the parameter" * Description of this parameters * used at: list of light source classes that use this parameter * nullable: yes if this field may be empty */ /* "location" * The location of the light source * used at: all * nullable: no */ Scientrace.Location location = this.X.getXLocation(xel, "Location", null); shadowLS.arguments.Add("location", location); /* "width" and "height" * The width of the light source * used at: random square light source * nullable: yes */ Scientrace.Vector width = this.X.getXLocation(xel, "Width", null); Scientrace.Vector height = this.X.getXLocation(xel, "Height", null); shadowLS.arguments.Add("width", width); shadowLS.arguments.Add("height", height); /* "ray count" * The number of traces that will be initiated by the light source, * some of the rays may be split or absorbed during simulation * Previously called: BeamCount, but renamed to RayCount. * used at: SpiralLightSource * nullable: no */ int ray_count = this.X.getXInt(xel, "RayCount", this.X.getXInt(xel, "BeamCount", 256)); shadowLS.arguments.Add("ray_count", ray_count); /* "loops" * The number of loops the spiral makes * used at: SpiralLightSource * nullable: yes */ if (this.X.hasAttribute(xel, "Loops")) { double?loops = this.X.getXNullDouble(xel, "Loops"); /* MOVED TO SPIRALLIGHTSOURCE * if (loops == -1) { * loops = 1.0154 * Math.Pow(Math.PI*2*(1-Math.Sqrt(((double)ray_count - 1) / (double)ray_count)), -0.5); * Console.WriteLine("Number of loops for "+ray_count+" beams set to: {"+loops.ToString("#,0.000")+"}."); * } */ shadowLS.arguments.Add("loops", loops); } /* "radius" * The radius for any circle shaped irradiating surface * used at: SpiralLightSource * nullable: no */ double?radius = this.X.getXNullDouble(xel, "Radius"); if (radius == null) { radius = this.X.getXNullDouble(xel, "Diameter") / 2; } if (radius != null && radius < 0) { throw new ArgumentOutOfRangeException("Radius " + radius + " out of range"); } shadowLS.arguments.Add("radius", radius); /* "distance" * In some cases the user might want to describe a surface/orientation where the * rays to trace pass, but should they actually start a given distance up front. * The distance parameter describes the distance to start "before" the given surface. * used at: SpiralLightSource * nullable: default = 0 */ shadowLS.arguments.Add("distance", this.X.getXDouble(xel, "Distance", 0)); /* "weighted_intensity" * The intensity of the entire lightsource may be weighted/redefined by setting its intensity. * nullable: yes * used at: all */ shadowLS.arguments.Add("weighted_intensity", this.X.getXNullDouble(xel, "Intensity")); /* "random_seed" * In order to make repreducable results, a randomized may be seeded * used at: RandomSquare * nullable: default = null */ shadowLS.arguments.Add("random_seed", this.X.getXNullInt(xel, "RandomSeed")); /* "direction" * The direction in which the rays leave the (parallel) source * used at: SpiralLightSource, RandomSquare * nullable: no */ shadowLS.arguments.Add("direction", this.X.getXUnitVectorByName(xel, "Direction", null)); /* "orthogonal to plane in which the "circle of light" is created" * used at: RandomCircleLightSource * nullable: yes */ shadowLS.arguments.Add("normal", this.X.getXUnitVectorByName(xel, "Normal", null)); /* "orthogonal to plane about which spiral is created" * sued at: SpiralLightSource * nullable: yes */ Scientrace.NonzeroVector spiral_axis = this.X.getXNzVectorByName(xel, "SpiralAxis", null); if (spiral_axis != null) { Scientrace.Plane spiralplane = Scientrace.Plane.newPlaneOrthogonalTo(location, spiral_axis); shadowLS.arguments.Add("spiral_plane", spiralplane); } /* "spectrum" * The wavelengths that are irradiated by the source with their relative intensities * used at: all except CustomTraces * */ XMLSpectrumParser xsp = new XMLSpectrumParser(); Scientrace.LightSpectrum spectrum = xsp.parseLightSpectrum(xel.Element("Spectrum")); //if (spectrum==null) { throw new Exception("LightSpectrum "+xel.Element("Spectrum").ToString()+" unknown"); } shadowLS.arguments.Add("spectrum", spectrum); /* "efficiency_characteristics" * If the performance of a cell depends on the angle of incidence or the wavelength of light, it can be defined * in efficiency_characteristics. The default fractions are "1" for both. * used at: all */ XMLEfficiencyCharacteristicsParser xecp = new XMLEfficiencyCharacteristicsParser(); Scientrace.OpticalEfficiencyCharacteristics oec = xecp.parseEfficiencyForLightSource(xel); shadowLS.arguments.Add("efficiency_characteristics", oec); /* "traces_list" * A generic List<Scientrace.Trace> with traces that are manually added to a lightsource. * used at: CustomTraces */ shadowLS.arguments.Add("traces_list", this.getCustomTracesListFromXData(xel, shadowLS.env)); }
/* end of intersectplanes function */ public Line reflectAt(Scientrace.Plane plane) { return(this.reflectLine(this.traceline, plane)); }
public void setUniformPolarisation() { Scientrace.Plane dummyPlane = Scientrace.Plane.newPlaneOrthogonalTo(Scientrace.Location.ZeroLoc(), this.traceline.direction); this.pol_vec_1 = dummyPlane.u.toVector()*Math.Sqrt(0.5*this.intensity); this.pol_vec_2 = dummyPlane.v.toVector()*Math.Sqrt(0.5*this.intensity); }
public Scientrace.SpiralLightSource setSpiralLightFromXData(XElement xlight, List <Scientrace.UniformTraceModifier> utms, Scientrace.Object3dEnvironment env) { /* "Spiral" * d class.radius, d class.loops, d distance, i beamcount, i maxinteractions, d minintensity * i modulomultiplier, str spectrum, vec location, vec direction */ double radius = this.X.getXDouble(xlight.Attribute("Radius")); if (radius < 0) { throw new ArgumentOutOfRangeException("Radius " + radius + " out of range"); } double distance = this.X.getXDouble(xlight.Attribute("Distance"), 0); int beamcount = this.X.getXInt(xlight.Attribute("RayCount"), this.X.getXInt(xlight.Attribute("BeamCount"))); //int maxinteractions = this.X.getXInt(xlight, "MaxInteractions", 8); //default value max_interactions -> 8 double minintensity = this.X.getXDouble(xlight, "MinIntensity", 0.2); //default minimum intensity for tracing set to 1% //Spiralspecific double loops = this.X.getXDouble(xlight, "Loops", -1); if (loops == -1) { loops = 1.0154 * Math.Pow(Math.PI * 2 * (1 - Math.Sqrt(((double)beamcount - 1) / (double)beamcount)), -0.5); Console.WriteLine("Number of loops for " + beamcount + " beams set to: {" + loops.ToString("#,0.000") + "}."); } Scientrace.NonzeroVector light_direction = this.X.getXNzVector(xlight.Element("Direction")); Scientrace.NonzeroVector spiral_axis = this.X.getXNzVector(xlight.Element("SpiralAxis")); Scientrace.Location centerloc = this.X.getXVector(xlight.Element("Location")).toLocation(); /*Scientrace.Location locoffset = (light_direction.toVector().negative()*distance).toLocation(); //distance cm above surface * Scientrace.Location loc = locoffset + centerloc; */ XMLSpectrumParser xsp = new XMLSpectrumParser(); Scientrace.LightSpectrum spectrum = xsp.parseLightSpectrum(xlight.Element("Spectrum")); if (spectrum == null) { throw new Exception("LightSpectrum " + xlight.Element("Spectrum").ToString() + " unknown"); } double divangle = 0; double divdistance = 0; Scientrace.NonzeroVector divpinvec = null; //= new Scientrace.NonzeroVector(0,1,0); int divsteps = 1; bool divincludebase = true; this.getDivergence(xlight, ref divangle, ref divpinvec, ref divdistance, ref divincludebase, ref divsteps); if (divangle > 0) { if (divpinvec.crossProduct(light_direction).length == 0) { throw new ArgumentOutOfRangeException("divpinvec", "Divergence Pinvector (" + divpinvec.trico() + ") is parallel to light directon (" + light_direction.trico() + ")"); } } // INSERT OPERATION THAT MAKES BOTH SPIRAL PLANE VECTORS ORTHOGONAL TO DIRECTION Scientrace.Plane spiralplane = Scientrace.Plane.newPlaneOrthogonalTo(centerloc, spiral_axis); //Scientrace.NonzeroVector direction = light_direction.tryToUnitVector(); Scientrace.SpiralLightSource retlight = new Scientrace.SpiralLightSource(env, centerloc, light_direction.toUnitVector(), spiralplane, beamcount, radius, loops, distance, spectrum); /* BEFORE REMOVAL OF DISPERSION_STEPS Scientrace.LightSource retlight = new Scientrace.SpiralLightSource(env, loc, light_direction.toUnitVector(), * spiralplane, beamcount, radius, loops, spectrum, * divangle, divpinvec, divdistance, divincludebase, divsteps); */ //retlight.max_interactions = maxinteractions; retlight.minimum_intensity_fraction = minintensity; retlight.lightsource_modifiers.AddRange(utms); //retlight.createStartTraces(); return(retlight); }
public Scientrace.Plane transformback(Scientrace.Plane plane) { return(new Scientrace.Plane(this.transformback(plane.loc), this.transformback(plane.u).tryToNonzeroVector(), this.transformback(plane.v).tryToNonzeroVector())); }
public void paramInit(Scientrace.Location center, Scientrace.UnitVector direction, Scientrace.Plane plane, int linecount, double radius, double loops, double distance) { this.loops = loops; this.radius = radius; this.center = center; //direction had been commented out. WHY? Re-enabled. this.direction = direction; this.spiral_plane = plane; this.tag = String.Format("{0:0.###}",loops)+"LoopSpiral"; this.distance = distance; //added later: this.linecount = linecount; //and removed again: //this.spectrum = spectrum; }
/// <summary> /// Copy Constructor Initializes a new instance of the <see cref="Scientrace.Plane"/> class. /// </summary> /// <param name='aPlane'> /// A plane instance with the same (copied) values (yet different instances) as parameters. /// </param> public Plane(Scientrace.Plane aPlane) { this.loc = aPlane.loc.copy(); this.u = aPlane.u.copy(); this.v = aPlane.v.copy(); }