/* 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;
        }
Example #2
0
 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)
 }