/* 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; }
public override Intersection intersects(Scientrace.Trace aTrace) { Scientrace.Vector c = this.loc; Scientrace.Vector o = aTrace.traceline.startingpoint; Scientrace.Vector l = aTrace.traceline.direction; Scientrace.Vector y = o-c; double r = this.radius; double ABCa = l.dotProduct(l); double ABCb = l.dotProduct(y)*2; double ABCc = y.dotProduct(y)-(r*r); QuadraticEquation qe = new QuadraticEquation(ABCa,ABCb,ABCc); // if the trace doesn't hit the sphere, return a "false Intersection" if (!qe.hasAnswers) { return new Intersection(false, this); } Scientrace.IntersectionPoint[] ips = new Scientrace.IntersectionPoint[2]; 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) }