public Scientrace.Rectangle parseXRectangleVectorBasedConstructor(XElement xsc) { Scientrace.Location location = this.X.getXLocation(xsc.Element("Location")); /* OLD method that caused a crashed on zerovectors. * Scientrace.NonzeroVector width = this.X.getXNzVector(xsc.Element("Width")); * Scientrace.NonzeroVector height = this.X.getXNzVector(xsc.Element("Height")); */ Scientrace.Vector vwidth = this.X.getXVector(xsc.Element("Width")); Scientrace.Vector vheight = this.X.getXVector(xsc.Element("Height")); if (vwidth.length * vheight.length == 0) { return(null); } Scientrace.NonzeroVector width = vwidth.tryToNonzeroVector(); Scientrace.NonzeroVector height = vheight.tryToNonzeroVector(); /*string materialid = this.X * .getXString(xsc.Attribute("Material")); * Scientrace.MaterialProperties material = Scientrace.MaterialProperties.FromIdentifier(materialid); */ Scientrace.MaterialProperties material = new ShadowClassConstruct(this.parentcollection).getXMaterial(xsc); //Console.WriteLine("MAT CELL: "+material.GetType()); Scientrace.Rectangle retcel = new Scientrace.Rectangle(this.parentcollection, material, location, width, height); this.addCommonObjectProperties(retcel, xsc); this.registerObject(xsc, retcel); return(retcel); }
public UniformTraceModifier(DistributionPattern distributionpattern, SpatialDistribution spatialdistribution, NonzeroVector meanvector) { this.distrPattern = distributionpattern; this.spatialDistribution = spatialdistribution; this.meanVec = meanvector; meanvector.fillOrtogonalVectors(ref this.baseVec1, ref this.baseVec2); }
public VectorTransformOrthonormal(NonzeroVector u, NonzeroVector v, NonzeroVector w) : base(u,v,w) { if (Math.Abs(this.u.dotProduct(this.v)) + Math.Abs(this.v.dotProduct(this.w)) + Math.Abs(this.w.dotProduct(this.u)) > 0) { throw new Exception("Vectors not orthogonal"); } this.normalize(); }
public string drawCircle(Scientrace.Location center, double radius, Scientrace.NonzeroVector aboutAxis) { return (this.getX3DTranslationTag(center) + //where this.getX3DRotationTag(NonzeroVector.z1vector(), aboutAxis) + //what direction "<Shape>" + this.emissiveColorAppearance(this.primaryRGB) + "<Circle2D radius='" + radius + "' />" + //what shape "</Shape></Transform></Transform>"); //close tags }
public VectorTransformOrthonormal(NonzeroVector u, NonzeroVector v, NonzeroVector w) : base(u, v, w) { if (Math.Abs(this.u.dotProduct(this.v)) + Math.Abs(this.v.dotProduct(this.w)) + Math.Abs(this.w.dotProduct(this.u)) > 0) { throw new Exception("Vectors not orthogonal"); } this.normalize(); }
public UniformTraceModifier(DistributionPattern distributionpattern, SpatialDistribution spatialdistribution, NonzeroVector meanvector, NonzeroVector basevector1, NonzeroVector basevector2) { this.distrPattern = distributionpattern; this.spatialDistribution = spatialdistribution; this.meanVec = meanvector; this.baseVec1 = basevector1; this.baseVec2 = basevector2; }
public VectorTransformOrthonormal(NonzeroVector u, NonzeroVector v) : base(u, v) { //if (this.u.dotProduct(this.v) != 0) { //please let's be a bit more tolerant because of rounding-errors if (Math.Abs(this.u.dotProduct(this.v)) > 0.000001) { throw new Exception("Vectors not orthogonal"); } this.normalize(); }
public VectorTransformOrthonormal(NonzeroVector u, NonzeroVector v) : base(u,v) { //if (this.u.dotProduct(this.v) != 0) { //please let's be a bit more tolerant because of rounding-errors if (Math.Abs(this.u.dotProduct(this.v)) > 0.000001) { throw new Exception("Vectors not orthogonal"); } this.normalize(); }
public StringBuilder drawSphereSlice(Scientrace.Object3d drawnObject3d, double lateral_circles, double meridians, Scientrace.Sphere sphere, double from_radians, double to_radians, Scientrace.UnitVector sliceAlongDirection) { System.Text.StringBuilder retx3d = new System.Text.StringBuilder(1024); //"<!-- DOUBLECONVEXLENS GRID start -->"); double pi2 = Math.PI * 2; NonzeroVector orthoBaseVec1 = null; NonzeroVector orthoBaseVec2 = null; sliceAlongDirection.fillOrtogonalVectors(ref orthoBaseVec1, ref orthoBaseVec2); for (double iSphereCircle = 2 * lateral_circles; iSphereCircle > 0; iSphereCircle--) // the rings/parallels along the sliceAlongDirection axis { double lateral_radians = (to_radians * (iSphereCircle / (2 * lateral_circles))); double circle2DRadius = sphere.radius * Math.Sin(lateral_radians); double circle2DDistance = sphere.radius * Math.Cos(lateral_radians); retx3d.Append(this.drawCircle(sphere.loc + (sliceAlongDirection * circle2DDistance).toLocation(), circle2DRadius, sliceAlongDirection)); for (double iSphereMerid = 0.5; iSphereMerid < 2 * meridians; iSphereMerid++) // meridians connect the rings/circles on the spherical surface { Scientrace.Location tNodeLoc = sphere.getSphericalLoc( orthoBaseVec1, orthoBaseVec2, sliceAlongDirection, to_radians * (iSphereCircle / (2 * lateral_circles)), // lat_angle = theta pi2 * (iSphereMerid / (2 * meridians)) // mer_angle = phi ); if (!tNodeLoc.isValid()) { throw new NullReferenceException("Cannot calculate base gridpoint at @ " + drawnObject3d.tag); } Scientrace.Location tLatConnectLoc = sphere.getSphericalLoc( orthoBaseVec1, orthoBaseVec2, sliceAlongDirection, to_radians * ((iSphereCircle - 1) / (2 * lateral_circles)), // lat_angle = theta pi2 * ((iSphereMerid) / (2 * meridians)) // mer_angle = phi ); if (!tLatConnectLoc.isValid()) { throw new NullReferenceException("Cannot calculate lateral gridpoint at @ " + drawnObject3d.tag); } Scientrace.X3DGridPoint tGridPoint = new Scientrace.X3DGridPoint(0, tNodeLoc, null, tLatConnectLoc); retx3d.AppendLine(tGridPoint.exportX3DnosphereRGB(this.primaryRGB)); } } // end for iSphereCircle / iSphereMerid return(retx3d); }
public static PlaneBorder createBetween3LocationsPointingTo(Scientrace.Location baseLoc, Scientrace.Location loc2, Scientrace.Location loc3, Scientrace.Location pointingToLoc) { Vector v1 = (loc2 - baseLoc).tryToUnitVector(); Vector v2 = (loc3 - baseLoc).tryToUnitVector(); NonzeroVector tryNormal = v1.crossProduct(v2).tryToNonzeroVector(); //Console.WriteLine("V1: "+v1.trico()+" v2:"+v2.trico()+" trynormal:"+tryNormal.trico()); PlaneBorder tryBorder = new PlaneBorder(baseLoc, tryNormal); if (tryBorder.contains(pointingToLoc)) { return(tryBorder); } tryBorder = new PlaneBorder(baseLoc, tryNormal.negative()); if (tryBorder.contains(pointingToLoc)) { return(tryBorder); } throw new Exception("Couldn't create PlaneBorder containing " + pointingToLoc.trico()); } //end createBetween3LocationsPoitningTo(...)
/// <summary> /// The distributionsquare is a measure for the equal-distribution of light over a surface. /// An entire surface is split up in quadrants out of which a measure is calculated by averaging /// the ratio between all quadrants and each other. Depending on the "order" each quadrant is having /// its own ratio calculated as well. For the weight of each order in the total is explained /// at the totalDistribution() method. /// </summary> /// <param name="order"> /// A <see cref="System.Int32"/> value containing the "currently calculated order". When manually /// creating a new DistributionSquare the top order should always be 0. Higher orders are created /// internally. /// </param> /// <param name="max_order"> /// How many orders should be calculated? A <see cref="System.Int32"/>. /// </param> /// <param name="loc"> /// The "top left" location of the surface. A <see cref="Location"/> /// </param> /// <param name="x"> /// The direction AND the width of the surface. A <see cref="NonzeroVector"/> /// </param> /// <param name="y"> /// The direction AND the height of the surface. A <see cref="NonzeroVector"/> /// </param> public DistributionSquare(int order, int max_order, Location loc, NonzeroVector x, NonzeroVector y) { this.order = order; this.max_order = max_order; this.x = x; this.y = y; this.loc = loc; if (order < max_order) { //Console.WriteLine("Smaller "+order+"/"+max_order+", so..."); this.tl = new DistributionSquare(order + 1, max_order, loc, x * 0.5, y * 0.5); this.tr = new DistributionSquare(order + 1, max_order, loc + (x * 0.5).toLocation(), x * 0.5, y * 0.5); this.bl = new DistributionSquare(order + 1, max_order, loc + (y * 0.5).toLocation(), x * 0.5, y * 0.5); this.br = new DistributionSquare(order + 1, max_order, loc + (x * 0.5 + y * 0.5).toLocation(), x * 0.5, y * 0.5); } this.trf = new VectorTransform(x, y); this.tx = this.trf.transform(this.x); this.ty = this.trf.transform(this.y); this.checkxy(); }
/* 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); }
/// <summary> /// Use function below to transform a vector over any angle v. Keep in mind that this /// function uses significantly more processingpower than the aboutX,Y,Z functions. /// </summary> /// <param name="v"> /// A <see cref="Scientrace.NonzeroVector"/> about which the vector should be rotated /// </param> /// <param name="radians"> /// A <see cref="System.Double"/> an angle in radians about which the vetor should be rotated /// anticlockwise with the vector V rising towards the viewer. /// </param> /// <returns> /// A <see cref="Vector"/> which is the result of the rotating operation. The original (this) /// vector is not modified during this operation. /// </returns> public Vector rotateAboutVector(Scientrace.NonzeroVector v, double radians) { NonzeroVector tv1; if (Math.Abs(new NonzeroVector(1, 0, 0).normalized().dotProduct(v.normalized())) < 0.9) { //throw new Exception("A: "+v.trico()+" cross: "+new NonzeroVector(1,0,0).crossProduct(v)); tv1 = new NonzeroVector(1, 0, 0).crossProduct(v).tryToNonzeroVector().normalized(); } else { tv1 = new NonzeroVector(0, 1, 0).crossProduct(v).tryToNonzeroVector().normalized(); } NonzeroVector tv2 = v.crossProduct(tv1).tryToNonzeroVector().normalized(); VectorTransformOrthonormal vtrf = new VectorTransformOrthonormal(tv1, tv2, v); Vector tvec = vtrf.transform(this); tvec = tvec.rotateAboutZ(radians); return(vtrf.transformback(tvec)); }
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.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 override string exportX3D(Scientrace.Object3dEnvironment env) { Scientrace.Location h1 = this.planoCenterLoc(); double r = this.sphereRadius; double x = this.getLensRadius(); double lensRadians = Math.Asin(x / r); NonzeroVector baseVecZ = this.lensPlane.getNormal(); NonzeroVector baseVec1 = null; NonzeroVector baseVec2 = null; baseVecZ.fillOrtogonalVectors(ref baseVec1, ref baseVec2); double lat_circles = 3; double meridians = 12; System.Text.StringBuilder retx3d = new System.Text.StringBuilder("<!-- PLANOCONVEXLENS GRID start -->", 1024); retx3d.Append("\t<!-- Plano part -->"); Scientrace.Location tNodeLoc; Scientrace.Location tMerConnectLoc; Scientrace.Location tLatConnectLoc; Scientrace.X3DGridPoint tGridPoint; double pi2 = Math.PI * 2; for (double iPlaneCircle = lat_circles; iPlaneCircle > 0; iPlaneCircle--) { for (double iPlaneMerid = 0; iPlaneMerid < meridians; iPlaneMerid++) { tNodeLoc = this.constructPlaneNodeLoc(h1, x * iPlaneCircle / lat_circles, pi2 * iPlaneMerid / meridians, baseVec1, baseVec2); tMerConnectLoc = this.constructPlaneNodeLoc(h1, x * iPlaneCircle / lat_circles, pi2 * (iPlaneMerid + 1) / meridians, baseVec1, baseVec2); tLatConnectLoc = this.constructPlaneNodeLoc(h1, x * (iPlaneCircle - 1) / lat_circles, pi2 * iPlaneMerid / meridians, baseVec1, baseVec2); tGridPoint = new Scientrace.X3DGridPoint(env, tNodeLoc, tMerConnectLoc, tLatConnectLoc); retx3d.AppendLine(tGridPoint.exportX3DnosphereRGBA("0.4 0 0.2 1")); } } //end for iPlaneCircles / iPlaneMerid retx3d.Append("\t<!-- End of plano part -->"); 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.constructSphereNodeLoc( lensRadians * (iSphereCircle / (2 * lat_circles)), // lat_angle = theta pi2 * (iSphereMerid / (2 * meridians)), // mer_angle = phi baseVec1, baseVec2, baseVecZ); tMerConnectLoc = this.constructSphereNodeLoc( lensRadians * (iSphereCircle / (2 * lat_circles)), // lat_angle = theta pi2 * ((iSphereMerid + 1) / (2 * meridians)), // mer_angle = phi baseVec1, baseVec2, baseVecZ); tLatConnectLoc = this.constructSphereNodeLoc( lensRadians * ((iSphereCircle - 1) / (2 * lat_circles)), // lat_angle = theta pi2 * (iSphereMerid / (2 * meridians)), // mer_angle = phi baseVec1, baseVec2, baseVecZ); tGridPoint = new Scientrace.X3DGridPoint(env, tNodeLoc, tMerConnectLoc, tLatConnectLoc); retx3d.AppendLine(tGridPoint.exportX3DnosphereRGBA("0.2 0 0.4 1")); } } // end for iSphereCircle / iSphereMerid retx3d.Append("\t<!-- Convex part -->"); retx3d.Append("\t<!-- End of Convex part -->"); retx3d.Append("<!-- End of PLANOCONVEXLENS GRID -->"); return(retx3d.ToString()); } //end string exportX3D(env)
/// <summary> /// Copy constructor /// </summary> /// <param name="copyVec">source data to be copied</param> public NonzeroVector(NonzeroVector copyVec) : base(copyVec.x, copyVec.y, copyVec.z) { this.init(); }
public new UnitVector reflectOnSurface(NonzeroVector norm) { return base.reflectOnSurface(norm).toUnitVector(); }
public Scientrace.NonzeroVector modify(Scientrace.NonzeroVector meanvector, double nodenumber, double nodetotal) { this.meanVec = meanvector; this.meanVec.fillOrtogonalVectors(ref this.baseVec1, ref this.baseVec2); return this.modify(nodenumber, nodetotal); }
public new NonzeroVector reflectOnSurface(NonzeroVector norm) { return(base.reflectOnSurface(norm).tryToNonzeroVector()); }
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)
public Scientrace.NonzeroVector modify(Scientrace.NonzeroVector meanvector, double nodenumber, double nodetotal) { this.meanVec = meanvector; this.meanVec.fillOrtogonalVectors(ref this.baseVec1, ref this.baseVec2); return(this.modify(nodenumber, nodetotal)); }
public new NonzeroVector reflectOnSurface(NonzeroVector norm) { return base.reflectOnSurface(norm).tryToNonzeroVector(); }
public new UnitVector reflectOnSurface(NonzeroVector norm) { return(base.reflectOnSurface(norm).toUnitVector()); }