/* 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);
        }
        /* 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);
        }