/// <summary> /// The parabolic mirror is one of the key elements of the SunCycle concentrator /// When light is directed onto a parabolic mirror in the right direction the /// lightrays will reflect towards a single point, hence it can be used as a concentrator. /// </summary> /// <param name="parent"> /// A <see cref="Scientrace.Object3dCollection"/> in which the physicalobject "parabolicmirror" is placed. /// </param> /// <param name="mprops"> /// A <see cref="Scientrace.MaterialProperties"/> instance defines the properties of the mirror. /// </param> /// <param name="loc"> /// A <see cref="Scientrace.Location"/> defines the location which has to be shifted to 0,0,0 to make z = x^2 + y^2 = 0 /// </param> /// <param name="zaxis"> /// A <see cref="Scientrace.UnitVector"/> pointing the direction of the norm at the "bottom" of the mirror pointing "up" /// </param> /// <param name="c"> /// A <see cref="System.Double"/>, the value c for which z = c(x^2+y^2) after a location shift. /// </param> /// <param name="cborder"> /// A <see cref="CylindricalBorder"/> the mirror only exists between these borders. /// </param> public ParabolicMirror(Scientrace.Object3dCollection parent, Scientrace.MaterialProperties mprops, Scientrace.Location loc, Scientrace.UnitVector zaxis, double c, AbstractGridBorder cborder) : base(parent, mprops) { /* Console.WriteLine("Mirror props: loc:"+ * loc.trico()+" zax:"+zaxis.trico()+ " c:"+c +" border: "+cborder.ToString()); */ this.c = c; this.loc = loc; this.zaxis = zaxis; this.cborder = cborder; Scientrace.UnitVector basevec1 = new Scientrace.UnitVector(1, 0, 0); if (Math.Abs(zaxis.dotProduct(basevec1)) > 0.8) { basevec1 = new Scientrace.UnitVector(0, 1, 0); } Scientrace.UnitVector v = basevec1.crossProduct(zaxis).tryToUnitVector(); trf = new VectorTransformOrthonormal(zaxis, v, VectorTransform.SWAP_U_WITH_W); //Console.WriteLine("V transform: "+trf.transform(v).trico()+ " z: "+zaxis+" transform(Z):"+trf.transform(zaxis).trico()); }
public override string exportX3D(Scientrace.Object3dEnvironment env) { int steps = this.exportX3Dgridsteps; Scientrace.AbstractGridBorder cborder = this.cborder; // Scientrace.VectorTransform cbordertrf = cborder.getTransform(); //Generate a rotating grid! Scientrace.VectorTransform cbordertrf = cborder.getGridTransform(this.zaxis); //Console.WriteLine("CBTRFcp: "+cbordertrf.ToCompactString()); /* * stloc: starting location actually representing the center of the border, * from there in the orthonormal direction of this border the collision points with * the parabolic mirror will be found (from -radius to +radius in both transform-directions */ Scientrace.Location stloc = cborder.getOrthoStartCenterLoc();// - cborder.getOthoDirection(); Scientrace.IntersectionPoint[] iparr, iparre, iparrs; Scientrace.Intersection cintr, eintr, sintr; /* * eloc is the location "east" of the current node, sloc "south" for drawing a grid * of course are terms east and south symbolic */ Scientrace.Location eloc, sloc; Scientrace.Line cline, eline, sline; //double r = cborder.getRadius(); double r1 = cborder.getURadius(); double r2 = cborder.getVRadius(); Scientrace.Vector v1 = cbordertrf.u.tryToUnitVector().toVector(); Scientrace.Vector v2 = cbordertrf.v.tryToUnitVector().toVector();; string retstr = ""; Scientrace.X3DGridPoint concentrationpoint = new Scientrace.X3DGridPoint(env, this.getConcentrationPoint(), null, null); retstr = concentrationpoint.x3DSphere(env.radius / 1000, "1 0 1", 0.5); retstr += concentrationpoint.x3DLineTo(this.loc, "1 0 1 1"); for (double ix = 0.5; ix < steps; ix++) { for (double iy = 0.5; iy <= steps; iy++) { /* Drawing a grid of lines in direction "border.orthodirection" to ParabolicMirror, * at every intersection a gridpoint is located. "cline" are those ortho-dir lines */ cline = new Scientrace.Line(((stloc - (v1 * r1) - (v2 * r2)) + (v1 * (r1 * 2 * (ix / steps))) + (v2 * (r2 * 2 * (iy / steps)))).toLocation(), cborder.getOrthoDirection()); // cborder.directionlength.toUnitVector()); /* USE THE "checkborder = false" function below to always * show the grid-points, also outside borders * iparr is the IntersectionPoint at the Parabolic Mirror for the current ix/iy iteration */ iparr = this.realIntersections(cline, true); /* DEBUG INFO foreach (IntersectionPoint ip in iparr) { * if (ip!=null) { * Console.WriteLine("IP AT: "+ip.ToString()); * } else { * Console.WriteLine("NO IP FROM: "+((stloc-(v1*r)-(v2*r))+(v1*(r*2*(ix/steps)))+(v2*(r*2*(iy/steps)))) +" AND "+cborder.getOrthoDirection()); * } * }*/ eline = new Scientrace.Line(((stloc - (v1 * r1) - (v2 * r2)) + (v1 * (r1 * 2 * ((ix + 1) / steps))) + (v2 * (r2 * 2 * (iy / steps)))).toLocation(), cborder.getOrthoDirection()); // cborder.directionlength.toUnitVector()); iparre = this.realIntersections(eline, true); //defining "east" neighbour eintr = new Intersection(eline, iparre, this); if (eintr.intersects) { eloc = eintr.enter.loc; } else { eloc = null; } sline = new Scientrace.Line(((stloc - (v1 * r1) - (v2 * r2)) + (v1 * (r1 * 2 * ((ix) / steps))) + (v2 * (r2 * 2 * ((iy + 1) / steps)))).toLocation(), cborder.getOrthoDirection()); // cborder.directionlength.toUnitVector()); iparrs = this.realIntersections(sline, true); //defining "south" neighbour sintr = new Intersection(sline, iparrs, this); if (sintr.intersects) { sloc = sintr.enter.loc; } else { sloc = null; } /* "central" point * where does line "cline" with intersections "iparr" intersect this object? */ cintr = new Intersection(cline, iparr, this, true); if (cintr.intersects) //add existing gridpoints { if (this.x3dgridspheres) { retstr = retstr + new X3DGridPoint(env, cintr.enter.loc, eloc, sloc).exportX3D(); } else { retstr = retstr + new X3DGridPoint(env, cintr.enter.loc, eloc, sloc).exportX3DnosphereRGBA("0 0 1 1"); } } } } //Console.WriteLine("!!!"+retstr); return(retstr + cborder.exportX3D(env)); }