/* Classes supporthing the creation of the lightsource */ public Scientrace.LightSource setRandomCylinderLightFromXData(XElement xlight, Scientrace.Object3dEnvironment env) { //Reading LightSource parameters from XML-element /* "RandomCylinder" * d class.radius, d distance, i beamcount, i maxinteractions, d minintensity * 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.Attribute("MaxInteractions"), 8); //default value max_interactions -> 8 double minintensity = this.X.getXDouble(xlight.Attribute("MinIntensity"), 0.01); //default minimum intensity for tracing set to 1% Scientrace.Vector light_direction = this.X.getXVector(xlight.Element("Direction")); Scientrace.Location centerloc = this.X.getXVector(xlight.Element("Location")).toLocation(); Scientrace.Location locoffset = (light_direction.negative() * distance).toLocation(); //distance cm above surface Scientrace.Location loc = locoffset + centerloc; XMLSpectrumParser xsp = new XMLSpectrumParser(); Scientrace.LightSpectrum spectrum = xsp.parseLightSpectrum(xlight.Element("Spectrum")); Scientrace.LightSource retlight = new Scientrace.RandomCircleLightSource(env, loc, light_direction.tryToUnitVector(), new Scientrace.Plane(new Scientrace.Location(0, 0, 0), new Scientrace.NonzeroVector(1, 0, 0), new Scientrace.NonzeroVector(0, 0, 1)), radius, beamcount, spectrum); //retlight.max_interactions = maxinteractions; retlight.minimum_intensity_fraction = minintensity; return(retlight); }
public void TestZeroAngleWith() { Scientrace.Vector v1, v2; v1 = new Scientrace.Vector(1, 1, 1); v2 = new Scientrace.Vector(1, 1, 1); Assert.AreEqual(0, v1.angleWith(v2)); }
} // 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 Scientrace.Vector lineThroughPlaneTLoc(Scientrace.Line line) { Scientrace.VectorTransform trf = this.getTransform(); //coordinates after coordinate-transformation. u->e1, v->e2, loc->eloc //the parallelogram is in the (a*e1, b*e2, 0) plane Scientrace.Vector eloc; eloc = this.geteloc(); //coordinates after coordinate-transformation. line.direction->eld, line.loc->ell Scientrace.Vector eld, ell; eld = trf.transform(line.direction); ell = trf.transform(line.startingpoint); //nbase is the new base when the parallelogram "location" has been substracted from the line-location Scientrace.Vector nbase = ell - eloc; //catch direction eld.z = 0; line is parallel to plane! if (eld.z == 0) { return(null); } double nx, ny, nz; double dfac = (nbase.z / eld.z); nx = nbase.x - (dfac * eld.x); ny = nbase.y - (dfac * eld.y); nz = nbase.z - (dfac * eld.z); //shift plane back to eloc location and return return((new Scientrace.Vector(nx, ny, nz)) + eloc); }
public Scientrace.Location constructPlaneNodeLoc(Scientrace.Location planeCenter, double radius, double angle, Scientrace.NonzeroVector baseVec1, Scientrace.NonzeroVector baseVec2) { Scientrace.Vector ix = baseVec1.toVector() * radius * Math.Sin(angle); Scientrace.Vector iy = baseVec2.toVector() * radius * Math.Cos(angle); return(planeCenter + ix + iy); }
public void TestAngleWith1() { Scientrace.Vector v1, v2; v1 = new Scientrace.Vector(1, 1, 1); v2 = new Scientrace.Vector(-1, -1, -1); Assert.AreEqual(Math.PI, v1.angleWith(v2)); }
public Scientrace.Vector rotateVectorForRotatedElementsIn(Scientrace.Vector aVector, XElement xe) { Scientrace.Vector retvec = aVector; // foreach(XElement rotated in xe.Elements("Rotated")) { // IN ORDER OF APPEARANCE foreach (XElement rotated in xe.Elements("Rotate")) // IN ORDER OF APPEARANCE { if (rotated == null) { continue; /* return aVector;*/ } double angle = 0; if (rotated.Element("Angle") == null) { throw new XMLException("Could not parse Angle for rotation"); } foreach (XElement xeangle in rotated.Elements("Angle")) { angle = angle + this.getXAngle(xeangle); } Scientrace.NonzeroVector rotaxis; try { rotaxis = this.getXNzVector(rotated.Element("AboutAxis")); } catch { throw new XMLException("Could not parse AboutAxis for rotation"); } /* rotation about an origin is obtained by first subtracting the "origin" vector, * then rotating about the axis normally and then adding the "origin" vector again */ Scientrace.Vector aboutOrigin = this.getXVector(rotated.Element("AboutOrigin"), Scientrace.Vector.ZeroVector()); //Console.WriteLine("ABOUT ORIGIN: "+aboutOrigin.trico()+"\n aBOUT aXIS: "+rotaxis.tricon()); retvec = (retvec - aboutOrigin).rotateAboutVector(rotaxis, angle) + aboutOrigin; //Scientrace.Vector fretvec = this.modifyVector(retvec, rotated); } return(retvec); }
public void TestAngleWith1() { Scientrace.Vector v1, v2; v1 = new Scientrace.Vector(1, 1, 1); v2 = new Scientrace.Vector(-1, -1, -1); Assert.AreEqual(Math.PI, v1.angleWith(v2)); }
public XElement setXRotationRad(Scientrace.Vector nonzeroAxis, double radians, object subElement) { XElement retx = this.setXRotationRad(nonzeroAxis, radians); retx.Add(subElement); return(retx); }
public Scientrace.Vector formulaVector(Scientrace.Vector aVector, XElement xformula) { string f_x = "x"; string f_y = "y"; string f_z = "z"; if (xformula.Attribute("xyz") != null) { try { string xyz = xformula.Attribute("xyz").Value; char[] delimiterChars = { ';', '\t' }; string[] elements = xyz.Split(delimiterChars); if (elements.Length != 3) { throw new XMLException("Element " + xformula.ToString() + " has \"" + elements.Length + "\" != 3 valid vector elements. "); } f_x = elements[0]; f_y = elements[1]; f_z = elements[2]; } catch { throw new XMLException("Formula " + xformula.ToString() + " does not have proper parameters for {xyz} attribute (can't parse {" + xformula.Attribute("xyz").Value.ToString() + "}. Perhaps incorrect use of PreProcess variables or decimal separators?)."); } } // attribute "xyz" f_x = this.getXStringByName(xformula, "x", f_x); f_y = this.getXStringByName(xformula, "y", f_y); f_z = this.getXStringByName(xformula, "z", f_z); Dictionary <string, object> replace_vectors = new Dictionary <string, object>() { { "x", (decimal)aVector.x }, { "y", (decimal)aVector.y }, { "z", (decimal)aVector.z } }; return(new Scientrace.Vector( Scientrace.MathStrings.solveString(f_x, replace_vectors), Scientrace.MathStrings.solveString(f_y, replace_vectors), Scientrace.MathStrings.solveString(f_z, replace_vectors) )); }
public void TestEqualsOperator() { Scientrace.Vector v1, v2; v1 = new Scientrace.Vector(1, 1, 1); v2 = new Scientrace.Vector(1, 1, 1); Assert.AreEqual(v1, v2); }
public Scientrace.Vector multiplyVector(Scientrace.Vector aVector, XElement xel) { double multiply_scalar = this.getXDouble(xel.Attribute("Factor"), 1); Scientrace.Vector multiplyvec = this.getXVectorSuggestions(xel, new Scientrace.Vector(1, 1, 1)); return((aVector * multiply_scalar).elementWiseProduct(multiplyvec)); }
/* Use functions below for nested element purposes */ //USING "object" instead of XElement or string for subelements public XElement setXVector(string elname, Scientrace.Vector v, object subElement) { XElement retx = this.setXVector(elname, v); retx.Add(subElement); return(retx); }
public XElement setXRotationDeg(Scientrace.Vector nonzeroAxis, double degrees, object subElement) { XElement retx = this.setXRotationDeg(nonzeroAxis, degrees); retx.Add(subElement); return(retx); }
public static void readCameraSettings(XElement x3d_or_xenv_element) { CustomXMLDocumentOperations X = new CustomXMLDocumentOperations(); Scientrace.Vector cameraviewpoint = Scientrace.TraceJournal.Instance.cameraviewpoint; Scientrace.Vector camrotationvec = Scientrace.TraceJournal.Instance.camrotationvector; Scientrace.TraceJournal.Instance.labelaxes = X.getXBool(x3d_or_xenv_element, "DrawAxes", Scientrace.TraceJournal.Instance.labelaxes); double camrotationangle = Scientrace.TraceJournal.Instance.camrotationangle; XElement camfrom = (x3d_or_xenv_element == null? null:x3d_or_xenv_element.Element("CameraFrom")); XElement camrot = (x3d_or_xenv_element == null? null:x3d_or_xenv_element.Element("CameraRotation")); if (camfrom != null) { cameraviewpoint = X.getXNzVector(camfrom); Scientrace.Vector camdirvec = cameraviewpoint.negative(); Scientrace.NonzeroVector defvec = new Scientrace.NonzeroVector(0, 0, -1); camrotationangle = defvec.angleWith(camdirvec); camrotationvec = defvec.crossProduct(camdirvec); } if (camrot != null) { camrotationvec = X.getXVectorByName(camrot, "Vector"); camrotationangle = X.getXAngleByName(camrot, "Angle"); } Scientrace.TraceJournal.Instance.cameraviewpoint = X.getXVectorByName(x3d_or_xenv_element, "CameraViewpoint", cameraviewpoint); Scientrace.TraceJournal.Instance.camrotationangle = camrotationangle; if (camrotationvec != null) { Scientrace.TraceJournal.Instance.camrotationvector = camrotationvec; } }
//.tryToUnitVector() public Vector orientedAlong(Scientrace.Vector aVector) { if (aVector.dotProduct(this) < 0) { return(this.negative()); } return(this); }
public XElement setXRotationDeg(Scientrace.Vector nonzeroAxis, string degrees) { XElement retx = new XElement("Rotated"); retx.Add(new XElement("Angle", new XAttribute("Degrees", degrees))); retx.Add(this.setXVector("AboutAxis", nonzeroAxis)); return(new XElement("Transformed", retx)); }
// Transform transformed location vector back to original base public Scientrace.Location lineThroughPlaneOLoc(Scientrace.Vector tloc) { if (tloc == null) { throw new Exception("Cannot transform a null vector (location)."); } return(this.getTransform().transformback(tloc).toLocation()); }
public new UnitVector orientedAgainst(Scientrace.Vector aVector) { if (aVector.dotProduct(this) > 0) { return(this.negative()); } return(this); }
/* end of nested element functions */ public XElement setXRotationRad(Scientrace.Vector nonzeroAxis, double radians) { XElement retx = new XElement("Rotated"); retx.Add(new XElement("Angle", new XAttribute("Radians", radians.ToString()))); retx.Add(this.setXVector("AboutAxis", nonzeroAxis)); return(new XElement("Transformed", retx)); }
public void RotateAboutY1() { Scientrace.Vector v1; v1 = new Scientrace.Vector(1, 0, 2).rotateAboutY(Math.PI / 2); Scientrace.Vector v2 = new Scientrace.Vector(2, 0, -1); Assert.AreEqual(v2.x, v1.x, 1E-15); Assert.AreEqual(v2.y, v1.y, 1E-15); Assert.AreEqual(v2.z, v1.z, 1E-15); }
public void RotateAboutZ1() { Scientrace.Vector v1; v1 = new Scientrace.Vector(1, 2, 0).rotateAboutZ(Math.PI/2); Scientrace.Vector v2 =new Scientrace.Vector(-2,1,0); Assert.AreEqual(v2.x, v1.x, 1E-15); Assert.AreEqual(v2.y, v1.y, 1E-15); Assert.AreEqual(v2.z, v1.z, 1E-15); }
public void RotateAboutZ1() { Scientrace.Vector v1; v1 = new Scientrace.Vector(1, 2, 0).rotateAboutZ(Math.PI / 2); Scientrace.Vector v2 = new Scientrace.Vector(-2, 1, 0); Assert.AreEqual(v2.x, v1.x, 1E-15); Assert.AreEqual(v2.y, v1.y, 1E-15); Assert.AreEqual(v2.z, v1.z, 1E-15); }
public Scientrace.NonzeroVector getXNzVectorSuggestions(XElement xe, string xmlname, Scientrace.Vector baseval) { if (xe.Element(xmlname) == null) { throw new XMLException("ERROR: (" + xmlname + ") not found in {" + xe.ToString() + "}"); } Scientrace.Vector retval = this.getXVectorSuggestions(xe.Element(xmlname), baseval); return(retval.tryToNonzeroVector("ERROR: (" + xmlname + ") may not be 0 in {" + xe.ToString() + "}")); }
public XElement setXVector(string elname, Scientrace.Vector v) { XElement retx = new XElement(elname); retx.Add(new XAttribute("x", v.x)); retx.Add(new XAttribute("y", v.y)); retx.Add(new XAttribute("z", v.z)); return(retx); }
public Scientrace.Vector geteloc() { //construction on request if (this.eloc == null) { this.eloc = this.getTransform().transform(this.loc); } return(this.eloc); }
public void RotateAboutY1() { Scientrace.Vector v1; v1 = new Scientrace.Vector(1, 0, 2).rotateAboutY(Math.PI/2); Scientrace.Vector v2 =new Scientrace.Vector(2,0, -1); Assert.AreEqual(v2.x, v1.x, 1E-15); Assert.AreEqual(v2.y, v1.y, 1E-15); Assert.AreEqual(v2.z, v1.z, 1E-15); }
public Scientrace.Vector getVector(string varname, Scientrace.Vector defval) { Scientrace.Vector retval = (Scientrace.Vector) this.getObject(varname, true); if (retval == null) { return(defval); } return(retval); }
public string spotSVGForWavelength(Scientrace.Vector location, double radius, double wavelength, double opacity) { Scientrace.TraceJournal tj = TraceJournal.Instance; return(@"<g> <circle cx='" + location.x + "' cy='" + location.y + "' r='" + radius + "' style='" + "fill:" + tj.wavelengthToRGB(wavelength) + ";fill-opacity:" + opacity + @";stroke:none'> <title>" + wavelength + @"nm</title> </circle> </g>"); }
/// <summary> /// Gets the cylindrical location. /// </summary> /// <returns> /// The cylindrical location based on a set of base vectors, /// the center of a sphere and two spherical locations on the sphere. /// </returns> /// <param name='xvec'> /// basevector X /// </param> /// <param name='yvec'> /// basevector Y /// </param> /// <param name='zvec'> /// basevector Z is the line in between theta = 0 and theta = pi. /// </param> /// <param name='sphereCenter'> /// Sphere center location /// </param> /// <param name='theta'> /// Theta runs from 0 to pi /// </param> /// <param name='phi'> /// Phi runs from 0 to 2*pi /// </param> public Location getEllipsoidLoc(Scientrace.Vector xvec, Scientrace.Vector yvec, Scientrace.Vector zvec, Scientrace.Vector sphereCenter, double theta, double phi) { return(( (((xvec * Math.Cos(phi)) + (yvec * Math.Sin(phi))) * Math.Sin(theta)) + (zvec * Math.Cos(theta)) + sphereCenter).toLocation()); }
public void testDotProductResults() { Random r = new Random(); for (int i = 0; i<1000; i++) { Scientrace.Vector a,b; a = new Scientrace.Vector(r.NextDouble()*100,r.NextDouble()*100,r.NextDouble()*100); b = new Scientrace.Vector(r.NextDouble()*100,r.NextDouble()*100,r.NextDouble()*100); Assert.LessOrEqual(Math.Abs(a.tryToUnitVector().dotProduct(b.tryToUnitVector())), 1); } }
public void TestVectorCrossProducts() { Scientrace.Vector x = Scientrace.Vector.x1vector(); Scientrace.Vector y = Scientrace.Vector.y1vector(); Scientrace.Vector z = Scientrace.Vector.z1vector(); Assert.AreEqual(x.crossProduct(y), z); Assert.AreEqual(y.crossProduct(x), z * -1); Assert.AreEqual(y.crossProduct(z), x); }
public void TestMinusOperator() { Scientrace.Vector v1, v2, v3; v1 = new Scientrace.Vector(1, 2, 3); v2 = new Scientrace.Vector(4, 1, 0.5); v3 = v1 - v2; Assert.AreEqual(-3, v3.x); Assert.AreEqual(1, v3.y); Assert.AreEqual(2.5, v3.z); }
/* CONSTRUCTORS */ public FlatSurfaceObject3d(ShadowScientrace.ShadowObject3d aShadowObject) : base(aShadowObject) { //only front surface by default: //this.x3d_fill = aShadowObject.getBool("x3d_fill", this.x3d_fill); this.x3d_fill_emissive_color = aShadowObject.getColorFromHTML("x3d_fill_emissive_color_html", this.x3d_fill_emissive_color); this.x3d_fill_diffuse_color = aShadowObject.getColorFromHTML("x3d_fill_diffuse_color_html", this.x3d_fill_diffuse_color); this.x3d_fill_bitmap = aShadowObject.getString("x3d_fill_bitmap"); this.x3d_fill_both_sides = aShadowObject.getBool("x3d_fill_both_sides", this.x3d_fill_both_sides); //this.x3d_fill_diffuse = aShadowObject.getBool("x3d_fill_diffuse", this.x3d_fill_diffuse); this.x3d_fill_normal = aShadowObject.getVector("x3d_fill_normal", this.x3d_fill_normal); }
/* CONSTRUCTORS */ public FlatSurfaceObject3d(ShadowScientrace.ShadowObject3d aShadowObject) : base(aShadowObject) { //only front surface by default: //this.x3d_fill = aShadowObject.getBool("x3d_fill", this.x3d_fill); this.x3d_fill_emissive_color = aShadowObject.getColorFromHTML("x3d_fill_emissive_color_html", this.x3d_fill_emissive_color); this.x3d_fill_diffuse_color = aShadowObject.getColorFromHTML("x3d_fill_diffuse_color_html", this.x3d_fill_diffuse_color); this.x3d_fill_bitmap = aShadowObject.getString("x3d_fill_bitmap"); this.x3d_fill_both_sides = aShadowObject.getBool("x3d_fill_both_sides", this.x3d_fill_both_sides); //this.x3d_fill_diffuse = aShadowObject.getBool("x3d_fill_diffuse", this.x3d_fill_diffuse); this.x3d_fill_normal = aShadowObject.getVector("x3d_fill_normal", this.x3d_fill_normal); }
public override Scientrace.VectorTransform createNewTransform() { Scientrace.Vector refvec; if (directionlength.toUnitVector().dotProduct(new Vector(1,0,0))<0.8) { refvec = new Vector(1,0,0); } else { refvec = new Scientrace.Vector(0,1,0); } Scientrace.NonzeroVector u, v; u = refvec.crossProduct(directionlength).tryToUnitVector()*this.radius; v = u.crossProduct(directionlength).tryToUnitVector()*this.radius; return new Scientrace.VectorTransform(u,v,this.directionlength); }
public Scientrace.VectorTransform createNewTransform() { Scientrace.Vector refvec; if (this.direction.dotProduct(new Vector(1,0,0))<0.8) { refvec = new Vector(1,0,0); } else { refvec = new Scientrace.Vector(0,1,0); } Scientrace.NonzeroVector u, v; //there used to be a *5 after lines below. TODO: check if OK like this u = refvec.crossProduct(this.direction).tryToUnitVector()*this.radius; v = u.crossProduct(this.direction).tryToUnitVector()*this.radius; return new Scientrace.VectorTransform(u,v,this.direction); }
public void TestIntersectionByVectorArray2() { Scientrace.Object3dEnvironment env = new Scientrace.Object3dEnvironment(Scientrace.AirProperties.Instance,100); Scientrace.Line beam = new Scientrace.Line(10, 10, 10, -1, -1, 0); Scientrace.LightSource light = new Scientrace.SingleRaySource(beam, 10, new Scientrace.AM15Spectrum(1), env); Scientrace.Trace trace = new Scientrace.Trace(500.0E-9, light, beam, env,1,1); Console.WriteLine(trace.ToString()); Scientrace.Vector v = new Scientrace.Vector(10,10,10); Scientrace.IntersectionPoint[] ips = new Scientrace.IntersectionPoint[2]; ips[0] = null; ips[1] = new Scientrace.IntersectionPoint(new Scientrace.Location(1,1,1), new Scientrace.FlatShape2d(v.toLocation(), new Scientrace.NonzeroVector(1,0,0), new Scientrace.NonzeroVector(0,1,0))); //Scientrace.Intersection intr = new Scientrace.Intersection(trace, ips); //Assert.IsTrue(intr.intersects); }
public Scientrace.Vector getXVectorSuggestions(XElement xe, Scientrace.Vector baseval) { if (xe == null) { throw new XMLException("XVector element does not exist"); } Scientrace.Vector retvec; if (xe.Attribute("xyz") != null) { retvec = this.getXVector(xe); } else { retvec = new Scientrace.Vector(this.getXDouble(xe, "x", baseval.x), this.getXDouble(xe, "y", baseval.y), this.getXDouble(xe, "z", baseval.z)); retvec = this.modifyVectorForSubElements(retvec, xe); } return retvec; }
public Scientrace.Vector lineThroughPlaneTLoc(Scientrace.Line line) { Scientrace.VectorTransform trf = this.getTransform(); //coordinates after coordinate-transformation. u->e1, v->e2, loc->eloc //the parallelogram is in the (a*e1, b*e2, 0) plane Scientrace.Vector eloc; eloc = this.geteloc(); //coordinates after coordinate-transformation. line.direction->eld, line.loc->ell Scientrace.Vector eld, ell; eld = trf.transform(line.direction); ell = trf.transform(line.startingpoint); //nbase is the new base when the parallelogram "location" has been substracted from the line-location Scientrace.Vector nbase = ell-eloc; //catch direction eld.z = 0; line is parallel to plane! if (eld.z == 0) { return null; } double nx, ny, nz; double dfac = (nbase.z/eld.z); nx = nbase.x-(dfac*eld.x); ny = nbase.y-(dfac*eld.y); nz = nbase.z-(dfac*eld.z); //shift plane back to eloc location and return return (new Scientrace.Vector(nx, ny, nz))+eloc; }
public Scientrace.Vector geteloc() { //construction on request if (this.eloc == null) { this.eloc = this.getTransform().transform(this.loc); } return this.eloc; }
public Scientrace.Vector dotProductMatrixWithVector(Scientrace.Vector a, Scientrace.Vector b, Scientrace.Vector c, Scientrace.Vector aVector) { Scientrace.Vector retvec = new Scientrace.Vector(0, 0, 0); Scientrace.Vector tvec = null; for (int irow = 0; irow <= 2; irow++) { tvec = new Vector(a.readIndex(irow), b.readIndex(irow), c.readIndex(irow)); retvec.onIndexWrite(irow, tvec.dotProduct(aVector)); } return retvec; }
public bool dictionaryCachedInverseVectors() { if (VectorTransform.inverseVectorDictionary.ContainsKey(this.idstring)) { //Console.WriteLine("Transform u="+this.u+", v="+this.v+", u="+this.w+"; has been FOUND in cache."); this.ui = VectorTransform.inverseVectorDictionary[idstring].ui; this.vi = VectorTransform.inverseVectorDictionary[idstring].vi; this.wi = VectorTransform.inverseVectorDictionary[idstring].wi; return true; } DateTime startTime = DateTime.Now; //Console.WriteLine("Transform u="+this.u+", v="+this.v+", u="+this.w+"; not found in cache."); this.initInverseVectors(); DateTime stopTime = DateTime.Now; VectorTransform.total_inverse_calculation_time += (stopTime-startTime); //LOCK CACHE SEMAPHORE VectorTransform.InverseVectorCacheSema.WaitOne(); //adding calculated item to cache if (VectorTransform.inverseVectorDictionary.ContainsKey(this.idstring)) { //do not add again, duplicate entry created at same time... Console.WriteLine("Duplicate entry..."); //RELEASE CACHE SEMAPHORE VectorTransform.InverseVectorCacheSema.Release(); return false; } //Add new entry. VectorTransform.inverseVectorDictionary.Add(this.idstring, this); //RELEASE CACHE SEMAPHORE VectorTransform.InverseVectorCacheSema.Release(); //Console.WriteLine("Element (u="+this.u+", v="+this.v+", w="+this.w+") added to cache. Current cache size: "+VectorTransform.inverseVectorDictionary.Count); return false; }
public void inituvw(Scientrace.Vector u, Scientrace.Vector v, Scientrace.Vector w) { this.u = u; this.v = v; this.w = w; this.idstring = this.getIdString(); if (VectorTransform.CACHE_TRANSFORMS) { this.cachedInverseVectors(); // Use this method for chached (better performance) transform retrieval } else { this.notCachedInverseVectors(); // Use this method for chached (less memory usage) transform retrieval } }
public void initInverseVectorsOPENTK() { Scientrace.Vector x = this.u; Scientrace.Vector y = this.v; Scientrace.Vector z = this.w; OpenTK.Matrix4d m = new OpenTK.Matrix4d( x.x, x.y, x.z, 0, y.x, y.y, y.z, 0, z.x, z.y, z.z, 0, 0, 0, 0, 1); m.Invert(); this.ui = new Scientrace.Vector(m.M11, m.M12, m.M13); this.vi = new Scientrace.Vector(m.M21, m.M22, m.M23); this.wi = new Scientrace.Vector(m.M31, m.M32, m.M33); }
private Scientrace.NonzeroVector calcTriangleHeightVector(ShadowObject3d sho3d) { Scientrace.Vector length = sho3d.getVector("length"); Scientrace.Vector width = sho3d.getVector("width"); Scientrace.Vector heightdir = sho3d.getVector("heightdir"); double angle = sho3d.getDouble("angle"); //create a vector orthogonal to length en width in the same binary direction as heightdir. Scientrace.UnitVector owl = (width.crossProduct(length) * Math.Sign(width.crossProduct(length).dotProduct(heightdir))).tryToUnitVector(); Scientrace.NonzeroVector bdir = ( //calculate the direction of the short side of the prism owl*Math.Sin(angle) + width.tryToUnitVector()*Math.Cos(angle) ).tryToNonzeroVector(); if ((bdir.length < 0.99999) || (bdir.length > 1.00001)) { throw new ArgumentOutOfRangeException("bdir.length", bdir.length, "!= 1"); } Scientrace.VectorTransform trf = new Scientrace.VectorTransform( width.tryToNonzeroVector(), owl.tryToNonzeroVector(), length.tryToNonzeroVector()); Scientrace.NonzeroVector hdirtrf = trf.transform(heightdir).tryToNonzeroVector(); Scientrace.Vector hprimetrf = new Scientrace.Vector(hdirtrf.x, hdirtrf.y, 0); //eliminate "length" component of heightdir in hprime //Console.WriteLine("HPRIMTRF:"+hprimetrf.trico()); Scientrace.NonzeroVector hprimedir = trf.transformback(hprimetrf).tryToNonzeroVector().normalized(); /* ^ * /C\ * / \ * h'/ \ b * / \ * /B_______A\ * width * angle = A; beta = B; gamma = C. */ //sine rule: hprimelen / sin A = width.length() / sin C = blen / sin B double beta, gamma; beta = Math.Acos(hprimedir.normalized().dotProduct(width.tryToNonzeroVector().normalized())); gamma = Math.PI - (angle + beta); double hprimelen; double sinruleconstant = width.length / Math.Sin(gamma); hprimelen = sinruleconstant*Math.Sin(angle); Scientrace.NonzeroVector hprime = hprimedir*hprimelen; // check: (trf.transform(hprime).x / hdirtrf.x) == (trf.transform(hprime).y / hdirtrf.y) double xycoeff = ((trf.transform(hprime).x / hdirtrf.x) / (trf.transform(hprime).y / hdirtrf.y)); if (Math.Abs(1-xycoeff)>0.00001) { //doesn't do anything if .x/.x = NaN, but that's OK for now. throw new ArgumentOutOfRangeException("xycoeff", xycoeff, "!=1"); } try { Scientrace.NonzeroVector h = ((Math.Abs(hdirtrf.x)>Math.Abs(hdirtrf.y)) ? // Preventing .x or .y denominator == 0 errors. trf.transformback(hdirtrf*(trf.transform(hprime).x / hdirtrf.x)) : trf.transformback(hdirtrf*(trf.transform(hprime).y / hdirtrf.y)) ).tryToNonzeroVector(); return h; } catch (Scientrace.ZeroNonzeroVectorException zne) { Console.WriteLine("ERROR: calculated height for triangularprism has length zero!"); throw (zne); } }
public Scientrace.Vector getXVector(XElement xe) { if (xe == null) { throw new XMLException("XVector element does not exist"); } XAttribute x, y, z; double dx, dy, dz; if (xe.Attribute("xyz") != null) { try { string xyz = xe.Attribute("xyz").Value; char[] delimiterChars = { ';', '\t' }; string[] elements = xyz.Split(delimiterChars); if (elements.Length !=3) { throw new XMLException("Element "+xe.ToString()+" has \""+elements.Length+ "\" != 3 valid vector elements. "); } dx=Convert.ToDouble(elements[0]); dy=Convert.ToDouble(elements[1]); dz=Convert.ToDouble(elements[2]); //Console.WriteLine("XYZ component values: x:"+dx+" y:"+dy+" z:"+dz); } catch { throw new XMLException("Element "+xe.ToString()+" does not have proper parameters for {xyz} attribute (can't parse {"+xe.Attribute("xyz").Value.ToString()+"}. Perhaps incorrect use of PreProcess variables or decimal separators?)."); } } else { try { x = xe.Attribute("x"); y = xe.Attribute("y"); z = xe.Attribute("z"); } catch { throw new XMLException("Element "+xe.ToString()+" does not have proper parameters {x,y,z}"); } try { dx = this.getXDouble(x); dy = this.getXDouble(y); dz = this.getXDouble(z); } catch { throw new XMLException("XVector "+xe.ToString()+ " contains values ("+x.ToString()+", "+y.ToString()+", "+z.ToString()+ ") that cannot be converted to floating point values."); } } Scientrace.Vector beforeModifyVec = new Scientrace.Vector(dx, dy, dz); Scientrace.Vector retvec = this.modifyVectorForSubElements(beforeModifyVec, xe); if (retvec==null) { Console.WriteLine("WARNING: NULL MODIFIED VECTOR FOUND FOR "+xe.ToString()); } return retvec; }
public void TestRotateAboutVector() { Scientrace.Vector v1 = new Scientrace.Vector(1,1,1); double angle = Math.PI/2; //a random angle /**/ Assert.AreEqual(v1.rotateAboutZ(angle), v1.rotateAboutVector(new Scientrace.NonzeroVector(0,0,1), angle) ); /* Assert.AreEqual(new Scientrace.Vector(1, -1, 1), v1.rotateAboutVector(new Scientrace.NonzeroVector(1,0,0), angle) );/* this will only fail due to significance */ /**/ Assert.AreEqual(v1.rotateAboutY(angle), v1.rotateAboutVector(new Scientrace.NonzeroVector(0,1,0), angle) );/**/ /**/ Assert.AreEqual(v1.rotateAboutX(angle), v1.rotateAboutVector(new Scientrace.NonzeroVector(1,0,0), angle) );/**/ }
public void TestVectorProjection() { Scientrace.Vector aVec = new Scientrace.Vector(0.2, 0.3, 0.4); Scientrace.UnitVector normal = new Scientrace.UnitVector(0,0,-1); Assert.AreEqual(aVec.projectOnPlaneWithNormal(normal), new Scientrace.Vector(0.2, 0.3, 0)); }
public void TestZeroAngleWith() { Scientrace.Vector v1, v2; v1 = new Scientrace.Vector(1, 1, 1); v2 = new Scientrace.Vector(1, 1, 1); Assert.AreEqual(0, v1.angleWith(v2)); }
public void TestEqualsOperator() { Scientrace.Vector v1, v2; v1 = new Scientrace.Vector(1, 1, 1); v2 = new Scientrace.Vector(1, 1, 1); Assert.AreEqual(v1, v2); }
public void TestMinusOperator() { Scientrace.Vector v1, v2, v3; v1 = new Scientrace.Vector(1, 2, 3); v2 = new Scientrace.Vector(4, 1, 0.5); v3 = v1-v2; Assert.AreEqual(-3, v3.x); Assert.AreEqual(1, v3.y); Assert.AreEqual(2.5, v3.z); }