/* interface IBorder3D implementation */ /// <summary> /// Return true when the specified aLocation is contained by the Sphere. If the /// </summary> /// <param name='aLocation'> /// If set to <c>true</c> a location. /// </param> public bool contains(Scientrace.Location aLocation) { VectorTransform trf = this.getTransform(); Location trLoc = trf.transform(aLocation - this.loc); return(((trLoc.x * trLoc.x) + (trLoc.y * trLoc.y) <= 1) == this.enclosesInside); }
/// <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(); }
/* end of interface IBorder3D implementation */ public IntersectionPoint[] intersectionPoints(Trace trace) { VectorTransform trf = this.getTransform(); // the points (any V) on the center line of this cylinder is described by "V = s + x l" for any x. Vector s = trf.transform(trace.traceline.startingpoint - this.loc); Vector l = trf.transform(trace.traceline.direction); double r = 1; // not (this.radius;) as the transformation rendered it 1. double ABCa = Math.Pow(l.x, 2) + Math.Pow(l.y, 2); double ABCb = 2 * ((s.x * l.x) + (s.y * l.y)); double ABCc = Math.Pow(s.x, 2) + Math.Pow(s.y, 2) - r * r; QuadraticEquation qe = new QuadraticEquation(ABCa, ABCb, ABCc); Scientrace.IntersectionPoint[] ips = new Scientrace.IntersectionPoint[2] { null, null }; if (!qe.hasAnswers) { return(ips); } for (int iAns = 1; iAns <= qe.answerCount; iAns++) { double x = qe.getAnswer(iAns); if (Double.IsNaN(x)) { throw new ArgumentNullException("Answer {" + iAns + "} is NaN.\n\n qe details:" + qe.ToString()); } Vector tLoc = s + (l * x); Vector tNormal = new Vector(tLoc.x, tLoc.y, 0); Location oLoc = (trf.transformback(tLoc) + this.loc).toLocation(); UnitVector oNormal = null; try { oNormal = trf.transformback(tNormal).tryToUnitVector(); } catch { new ZeroNonzeroVectorException("oNormal is a zerovector which cannot be normalised for o3d [" + this.tag + "] and trace " + trace.ToCompactString()); } ips[iAns - 1] = Scientrace.IntersectionPoint.locAtSurfaceNormal(oLoc, oNormal); } /* switch (qe.answerCount) { * case 2: * Scientrace.Location minLoc = ((l*qe.minVal) + o).toLocation(); * Scientrace.NonzeroVector minNorm = (minLoc - c).tryToNonzeroVector(); * ips[0] = Scientrace.IntersectionPoint.locAtSurfaceNormal(minLoc, minNorm); * Scientrace.Location plusLoc = ((l*qe.plusVal) + o).toLocation(); * Scientrace.NonzeroVector plusNorm = (plusLoc - c).tryToNonzeroVector(); * ips[1] = Scientrace.IntersectionPoint.locAtSurfaceNormal(plusLoc, plusNorm); * return new Intersection(aTrace, ips, this); * //goto case 1; //continue to case 1 * case 1: * Scientrace.Location loc = ((l*qe.plusVal) + o).toLocation(); * Scientrace.NonzeroVector norm = (loc - c).tryToNonzeroVector(); * ips[0] = Scientrace.IntersectionPoint.locAtSurfaceNormal(loc, norm); * ips[1] = null; * return new Intersection(aTrace, ips, this); * default: * throw new IndexOutOfRangeException("eq.answerCount is not allowed to be "+qe.answerCount.ToString()+"in Shpere.intersects(..)"); * } //end switch(qe.answerCount) */ return(ips); }