public override Scientrace.VectorTransform getGridTransform(UnitVector nz) { //construction on request if (this.gridtrf == null) { Scientrace.Vector refvec; //vector has to differ at least 1% from the orthogonal orientation. if (Math.Abs(directionlength.toUnitVector().dotProduct(nz)) < 0.99) { refvec = nz; } else { refvec = (nz.rotateAboutX(Math.PI / 2).rotateAboutY(Math.PI / 2)).tryToUnitVector(); if (Math.Abs(directionlength.toUnitVector().dotProduct(nz)) < 0.99) { throw new Exception("WARNING: CrossProducts cannot produce orthogonal lines over two parallel " + "vectors, two vectors that are almost parallel will give a large significance error. FIX DIDN'T WORK, please contact the Scientrace developer."); } } Scientrace.NonzeroVector u, v; u = refvec.crossProduct(directionlength).tryToUnitVector() * this.radius; v = u.crossProduct(directionlength).tryToUnitVector() * this.radius; this.gridtrf = new Scientrace.VectorTransform(u, v, this.directionlength); } return(this.gridtrf); }
public void PGramDiagonalSurfacePerformanceTest() { DateTime startTime = DateTime.Now; double x1, x2, y1, y2, z1, z2, foo = 1; for (x1 = 0; x1 < 10000; x1++) { x2 = -3; y1 = 56; y2 = 12; z1 = -2; z2 = 23; Scientrace.NonzeroVector nzv1 = new Scientrace.NonzeroVector(x1, y1, z1); Scientrace.NonzeroVector nzv2 = new Scientrace.NonzeroVector(x2, y2, z2); Scientrace.Parallelogram a = new Scientrace.Parallelogram(new Scientrace.Location(1, 2, 3), nzv1, nzv2); //comparing surface calculated by sine of the angle between vectors and multiplication with their lengths with the lenght of the outproduct if (Math.Sin(Math.Acos(nzv1.toUnitVector().dotProduct(nzv2.toUnitVector())))*nzv1.length*nzv2.length != a.getSurfaceSize()) { //Assert.AreEqual(Math.Sin(Math.Acos(nzv1.toUnitVector().dotProduct(nzv2.toUnitVector())))*nzv1.length*nzv2.length, a.getSurface(), 1e-10); foo++; } } DateTime stopTime = DateTime.Now; TimeSpan duration = stopTime-startTime; Console.WriteLine(foo.ToString()+" siginificance failures"); //making sure these 10 000 dotproducts and crossproducts comparisons can be executed within 60 milliseconds Assert.Less(duration.Milliseconds, 60); }
public void PGramDiagonalSurfacePerformanceTest() { DateTime startTime = DateTime.Now; double x1, x2, y1, y2, z1, z2, foo = 1; for (x1 = 0; x1 < 10000; x1++) { x2 = -3; y1 = 56; y2 = 12; z1 = -2; z2 = 23; Scientrace.NonzeroVector nzv1 = new Scientrace.NonzeroVector(x1, y1, z1); Scientrace.NonzeroVector nzv2 = new Scientrace.NonzeroVector(x2, y2, z2); Scientrace.Parallelogram a = new Scientrace.Parallelogram(new Scientrace.Location(1, 2, 3), nzv1, nzv2); //comparing surface calculated by sine of the angle between vectors and multiplication with their lengths with the lenght of the outproduct if (Math.Sin(Math.Acos(nzv1.toUnitVector().dotProduct(nzv2.toUnitVector()))) * nzv1.length * nzv2.length != a.getSurfaceSize()) { //Assert.AreEqual(Math.Sin(Math.Acos(nzv1.toUnitVector().dotProduct(nzv2.toUnitVector())))*nzv1.length*nzv2.length, a.getSurface(), 1e-10); foo++; } } DateTime stopTime = DateTime.Now; TimeSpan duration = stopTime - startTime; Console.WriteLine(foo.ToString() + " siginificance failures"); //making sure these 10 000 dotproducts and crossproducts comparisons can be executed within 60 milliseconds Assert.Less(duration.Milliseconds, 60); }
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 void PGramDiagonalSurfaceTest2() { double x1, x2, y1, y2, z1, z2; x1 = 4; x2 = -3; y1 = 56; y2 = 12; z1 = -2; z2 = 23; Scientrace.NonzeroVector nzv1 = new Scientrace.NonzeroVector(x1, y1, z1); Scientrace.NonzeroVector nzv2 = new Scientrace.NonzeroVector(x2, y2, z2); Scientrace.Parallelogram a = new Scientrace.Parallelogram(new Scientrace.Location(1, 2, 3), nzv1, nzv2); //comparing surface calculated by sine of the angle between vectors and multiplication with their lengths with the lenght of the outproduct Assert.AreEqual( Math.Sin(Math.Acos(nzv1.toUnitVector().dotProduct(nzv2.toUnitVector()))) * nzv1.length * nzv2.length, a.getSurfaceSize(), 1E-12); }
public static Scientrace.Plane newPlaneOrthogonalTo(Scientrace.Location loc, Scientrace.NonzeroVector normalVec, Scientrace.NonzeroVector helpVec1, Scientrace.NonzeroVector helpVec2) { Scientrace.UnitVector unitvec = normalVec.toUnitVector(); Scientrace.UnitVector h1 = helpVec1.toUnitVector(); Scientrace.UnitVector h2 = helpVec2.toUnitVector(); if (h1.dotProduct(h2) >= 1) { throw new Scientrace.ParallelVectorException(h1, h2, " in newPlaneOrthogonalTo(3) factory method."); } Scientrace.UnitVector refvec = ( (Math.Abs(unitvec.dotProduct(h1)) < 0.8) ? h1 : h2 ); Scientrace.NonzeroVector u = unitvec.crossProduct(refvec).tryToUnitVector(); Scientrace.NonzeroVector v = unitvec.crossProduct(u).tryToUnitVector(); return(new Scientrace.Plane(loc, u, v)); }
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.SingleRaySource setSingleRayFromXData(XElement xlight, List <Scientrace.UniformTraceModifier> utms, Scientrace.Object3dEnvironment env) { double distance = this.X.getXDouble(xlight.Attribute("Distance"), 0); int beamcount = this.X.getXInt(xlight.Attribute("RayCount"), this.X.getXInt(xlight.Attribute("BeamCount"), 1)); double minintensity = this.X.getXDouble(xlight, "MinIntensity", 0.01); //default minimum intensity for tracing set to 1% Scientrace.NonzeroVector light_direction = this.X.getXNzVector(xlight.Element("Direction")); 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"); } Scientrace.SingleRaySource retlight = new Scientrace.SingleRaySource(new Scientrace.Line(loc, light_direction.toUnitVector()), beamcount, spectrum, env); retlight.minimum_intensity_fraction = minintensity; retlight.lightsource_modifiers.AddRange(utms); retlight.init(); return(retlight); }
public void PGramDiagonalSurfaceTest2() { double x1, x2, y1, y2, z1, z2; x1 = 4; x2 = -3; y1 = 56; y2 = 12; z1 = -2; z2 = 23; Scientrace.NonzeroVector nzv1 = new Scientrace.NonzeroVector(x1, y1, z1); Scientrace.NonzeroVector nzv2 = new Scientrace.NonzeroVector(x2, y2, z2); Scientrace.Parallelogram a = new Scientrace.Parallelogram(new Scientrace.Location(1, 2, 3), nzv1, nzv2); //comparing surface calculated by sine of the angle between vectors and multiplication with their lengths with the lenght of the outproduct Assert.AreEqual( Math.Sin(Math.Acos(nzv1.toUnitVector().dotProduct(nzv2.toUnitVector())))*nzv1.length*nzv2.length, a.getSurfaceSize(), 1E-12); }
public override string exportX3D(Scientrace.Object3dEnvironment env) { double r1 = this.sphere1Radius; double r2 = this.sphere2Radius; //used to say sphere1Radius too? //The lensRadians is the angle made from the center of a sphere along the center of the lens to the side of the lens. double lens1Radians = this.getRadiansSphere1(); double lens2Radians = this.getRadiansSphere2(); Scientrace.NonzeroVector lens1to2Dir = (dummySphere2.loc - dummySphere1.loc).tryToUnitVector() * Math.Sign(r1) * Math.Sign(r2); Scientrace.NonzeroVector lens1Dir = lens1to2Dir * Math.Sign(r2); Scientrace.NonzeroVector lens2Dir = lens1to2Dir * -1 * Math.Sign(r1); NonzeroVector baseVec1 = null; NonzeroVector baseVec2 = null; lens1to2Dir.fillOrtogonalVectors(ref baseVec1, ref baseVec2); double lat_circles = 3; double meridians = 12; System.Text.StringBuilder retx3d = new System.Text.StringBuilder(2000); retx3d.AppendLine("<!-- DOUBLECONVEXLENS GRID start -->"); X3DShapeDrawer xsd = new X3DShapeDrawer(); xsd.primaryRGB = "0.4 0 0.2"; retx3d.Append(xsd.drawSphereSlice(this, lat_circles, meridians, this.dummySphere1, 0, lens1Radians, lens1Dir.toUnitVector())); retx3d.Append(xsd.drawSphereSlice(this, lat_circles, meridians, this.dummySphere2, 0, lens2Radians, lens2Dir.toUnitVector())); retx3d.AppendLine("<!-- DOUBLECONVEXLENS GRID end -->"); return(retx3d.ToString()); /* * Scientrace.Location tNodeLoc; * Scientrace.Location tMerConnectLoc; * Scientrace.Location tLatConnectLoc; * Scientrace.X3DGridPoint tGridPoint; * double pi2 = Math.PI*2; * * retx3d.Append("\t<!-- Convex part -->" ); * * for (double iSphereCircle = 2*lat_circles; iSphereCircle > 0; iSphereCircle--) { * for (double iSphereMerid = 0.5; iSphereMerid < 2*meridians; iSphereMerid++) { * //double lat_angle = lensRadians * (iSphereCircle / lat_circles); // theta * //double mer_angle = pi2 * (iSphereMerid/meridians); // mer_angle = phi * * tNodeLoc = this.dummySphere1.getSphericalLoc( * baseVec1, baseVec2, * lens1to2Dir, * lens1Radians * (iSphereCircle / (2*lat_circles)), // lat_angle = theta * pi2 * (iSphereMerid/(2*meridians)) // mer_angle = phi * ); * if (!tNodeLoc.isValid()) * throw new NullReferenceException("Cannot calculate base gridpoint at @ "+this.tag); * tMerConnectLoc = this.dummySphere1.getSphericalLoc( * baseVec1, baseVec2, * lens1to2Dir, * lens1Radians * (iSphereCircle / (2*lat_circles)), // lat_angle = theta * pi2 * ((iSphereMerid+1)/(2*meridians)) // mer_angle = phi * ); * if (!tMerConnectLoc.isValid()) * throw new NullReferenceException("Cannot calculate meridian gridpoint at @ "+this.tag); * * tLatConnectLoc = this.dummySphere1.getSphericalLoc( * baseVec1, baseVec2, * lens1to2Dir, * lens1Radians * ((iSphereCircle-1) / (2*lat_circles)), // lat_angle = theta * pi2 * ((iSphereMerid)/(2*meridians)) // mer_angle = phi * ); * if (!tLatConnectLoc.isValid()) * throw new NullReferenceException("Cannot calculate lateral gridpoint at @ "+this.tag); * * tGridPoint = new Scientrace.X3DGridPoint(env, tNodeLoc, tMerConnectLoc, tLatConnectLoc); * retx3d.AppendLine(tGridPoint.exportX3Dnosphere("0.2 0 0.4 1")); * }} // end for iSphereCircle / iSphereMerid * retx3d.Append("\t<!-- End of Convex part -->" ); * retx3d.Append("<!-- End of DOUBLECONVEXLENS GRID -->"); */ } //end string exportX3D(env)