public void TestFailingRealIntersections()
        {
            Scientrace.Object3dEnvironment env = DummySources.dEnv();
            Scientrace.CylindricalBorder   cb  = new Scientrace.CylindricalBorder(new Scientrace.Location(0, -0.07, 0), new Scientrace.NonzeroVector(0, -0.57, 0), 0.5);
            Scientrace.ParabolicMirror     pm  = new Scientrace.ParabolicMirror(env
                                                                                , Scientrace.PerfectMirror.Instance, new Scientrace.Location(0.354861881099294, -0.57, 0.276718350209505)
                                                                                , new Scientrace.UnitVector(-0.343710964996787, 0.900014703397015, -0.268022958363946), 2, cb);
            Scientrace.Line tl = new Scientrace.Line(-0.184140645666577, -0.0383229578843359, -0.3, 0.343710966184079, -0.900014705907235, 0.268022948412108);

//		pm.trf.transform(tl);
//		Scientrace.IntersectionPoint[] tips = pm.realIntersections(tl);
            //Assert.AreEqual(new Scientrace.Location(0,0,0), tips[0].loc);

            Scientrace.VectorTransform trf     = pm.trf;
            Scientrace.Line            trfline = trf.transform(tl - pm.loc);
            //transform location AND direction
            Scientrace.IntersectionPoint[] ips = pm.baseintersections(trfline);
            //Scientrace.IntersectionPoint tip;
            Scientrace.IntersectionPoint[] retips = new Scientrace.IntersectionPoint[2];
            for (int ipi = 0; ipi < ips.GetLength(0); ipi++)
            {
                if (ips[ipi] == null)
                {
                    retips[ipi] = null;
                    continue;
                }

                //check below removed for performance reasons
                if (!trfline.throughLocation(ips[ipi].loc, 0.00001))
                {
                    string warning = @"ERROR: GOING DOWN! \n baseintersections " + trfline + " FAILED!";
                    throw new ArgumentOutOfRangeException(warning + ips[ipi].loc.trico() + " not in line " + trfline);
                }
            }
        }
        public void TestFailingRealIntersections()
        {
            Scientrace.Object3dEnvironment env = DummySources.dEnv();
            Scientrace.CylindricalBorder cb = new Scientrace.CylindricalBorder(new Scientrace.Location(0, -0.07, 0), new Scientrace.NonzeroVector(0, -0.57, 0), 0.5);
            Scientrace.ParabolicMirror pm = new Scientrace.ParabolicMirror(env
            , Scientrace.PerfectMirror.Instance, new Scientrace.Location(0.354861881099294, -0.57, 0.276718350209505)
            ,  new Scientrace.UnitVector(-0.343710964996787, 0.900014703397015, -0.268022958363946), 2, cb);
            Scientrace.Line tl = new Scientrace.Line(-0.184140645666577, -0.0383229578843359, -0.3, 0.343710966184079, -0.900014705907235, 0.268022948412108);

            //		pm.trf.transform(tl);
            //		Scientrace.IntersectionPoint[] tips = pm.realIntersections(tl);
            //Assert.AreEqual(new Scientrace.Location(0,0,0), tips[0].loc);

            Scientrace.VectorTransform trf = pm.trf;
            Scientrace.Line trfline = trf.transform(tl-pm.loc);
                    //transform location AND direction
            Scientrace.IntersectionPoint[] ips = pm.baseintersections(trfline);
            //Scientrace.IntersectionPoint tip;
            Scientrace.IntersectionPoint[] retips = new Scientrace.IntersectionPoint[2];
            for (int ipi = 0; ipi < ips.GetLength(0); ipi++) {
                if (ips[ipi] == null) {
                    retips[ipi] = null;
                    continue;
                }

                //check below removed for performance reasons
                if (!trfline.throughLocation(ips[ipi].loc, 0.00001)) {
                    string warning =@"ERROR: GOING DOWN! \n baseintersections "+trfline+" FAILED!";
                    throw new ArgumentOutOfRangeException(warning+ips[ipi].loc.trico() + " not in line " + trfline);
                }
            }
        }
Exemple #3
0
 //copy constructor
 public Intersection(Intersection copyIntersection)
 {
     this.intersects = copyIntersection.intersects;
     this.object3d = copyIntersection.object3d;
     this.leaving = copyIntersection.leaving;
     if (copyIntersection.enter != null)
     this.enter = new Scientrace.IntersectionPoint(copyIntersection.enter);
     if (copyIntersection.exit != null)
     this.exit = new Scientrace.IntersectionPoint(copyIntersection.exit);
 }
 public Scientrace.IntersectionPoint filterOutsideBorder(Scientrace.IntersectionPoint anIP)
 {
     if (anIP == null)
     {
         return(null);
     }
     return
         (this.contains(anIP.loc)
                 ? anIP
                 : null);
 }
Exemple #5
0
 //copy constructor
 public Intersection(Intersection copyIntersection)
 {
     this.intersects = copyIntersection.intersects;
     this.object3d   = copyIntersection.object3d;
     this.leaving    = copyIntersection.leaving;
     if (copyIntersection.enter != null)
     {
         this.enter = new Scientrace.IntersectionPoint(copyIntersection.enter);
     }
     if (copyIntersection.exit != null)
     {
         this.exit = new Scientrace.IntersectionPoint(copyIntersection.exit);
     }
 }
        public IntersectionPoint[] intersects11circleborder(Trace trace)
        {
            Scientrace.Line line = trace.traceline;
            double          d1, d2, dx, dy, lx, ly;
            double          ABCa, ABCb, ABCc, discr;

            Scientrace.Vector              v1, v2;
            Scientrace.FlatShape2d         plane1, plane2;
            Scientrace.IntersectionPoint[] ip;
            dx = line.direction.x;
            dy = line.direction.y;
            lx = line.startingpoint.x;
            ly = line.startingpoint.y;

            ABCa  = Math.Pow(ly, 2) + Math.Pow(lx, 2);
            ABCb  = 2 * ((ly * dy) + (lx * dx));
            ABCc  = Math.Pow(dy, 2) + Math.Pow(dx, 2) - 1;
            discr = Math.Pow(ABCb, 2) - (4 * ABCa * ABCc);
            if (discr < 0)
            {
                ip = new Scientrace.IntersectionPoint[0];
                //ip[0] = null;
                //ip[1] = null;
                return(ip);
            }
            if (discr == 0)
            {
                ip = new Scientrace.IntersectionPoint[1];
                d1 = ((-ABCb) + Math.Sqrt(Math.Pow(ABCb, 2) - (4 * ABCa * ABCc))) / (2 * ABCa);
                v1 = (line.direction.toVector() * d1) + line.startingpoint.toVector();
                //plane1 is based on v1 rotated 90 degrees which makes: x' = -y, y' = x, z = z
                plane1 = new Scientrace.FlatShape2d(v1.toLocation(), new Scientrace.UnitVector(0, 0, 1),
                                                    new Scientrace.UnitVector(-v1.y, v1.x, v1.z));
                ip[0] = new IntersectionPoint(v1.toLocation(), plane1);
                return(ip);
            }
            d1     = ((-ABCb) + Math.Sqrt(Math.Pow(ABCb, 2) - (4 * ABCa * ABCc))) / (2 * ABCa);
            d2     = ((-ABCb) - Math.Sqrt(Math.Pow(ABCb, 2) - (4 * ABCa * ABCc))) / (2 * ABCa);
            v1     = (line.direction.toVector() * d1) + line.startingpoint.toVector();
            v2     = (line.direction.toVector() * d2) + line.startingpoint.toVector();
            ip     = new Scientrace.IntersectionPoint[2];
            plane1 = new Scientrace.FlatShape2d(v1.toLocation(), new Scientrace.UnitVector(0, 0, 1),
                                                new Scientrace.UnitVector(-v1.y, v1.x, v1.z));
            ip[0]  = new IntersectionPoint(v1.toLocation(), plane1);
            plane2 = new Scientrace.FlatShape2d(v2.toLocation(), new Scientrace.UnitVector(0, 0, 1),
                                                new Scientrace.UnitVector(-v2.y, v2.x, v2.z));
            ip[1] = new IntersectionPoint(v2.toLocation(), plane2);
            return(ip);
        }
Exemple #7
0
        public Intersection(bool intersects, Scientrace.Object3d object3d, Scientrace.Location enterloc, 
						Scientrace.FlatShape2d enterplane, Scientrace.Location exitloc, bool leaving)
        {
            this.intersects = intersects;
            this.object3d = object3d;
            this.enter = new IntersectionPoint(enterloc, enterplane);
            //plane of exitloc irrelevant
            if (exitloc == null) {
            this.exit = null;
            } else {
            this.exit = new IntersectionPoint(exitloc, null);
            }
            this.leaving = leaving;
            this.checkObject();//<- DEBUGGING:
        }
Exemple #8
0
        public Intersection(bool intersects, Scientrace.Object3d object3d, Scientrace.Location enterloc, 
						Scientrace.FlatShape2d enterplane, Scientrace.Location exitloc)
        {
            //same as constructor above but with leaving = false.
            this.intersects = intersects;
            this.object3d = object3d;
            this.enter = new IntersectionPoint(enterloc, enterplane);
            if (exitloc == null) {
            this.exit = null;
            } else {
            this.exit = new IntersectionPoint(exitloc, null);
            }
            this.leaving = false;
            this.checkObject();//<- DEBUGGING:
        }
 public void TestIntersectionByVectorArray3()
 {
     Scientrace.Object3dEnvironment env = new Scientrace.Object3dEnvironment(Scientrace.AirProperties.Instance, 100);
     Scientrace.Line        beam        = new Scientrace.Line(10, 10, 10, -1, -1, 0);
     Scientrace.LightSource light       = new Scientrace.SingleRaySource(beam,
                                                                         10, new Scientrace.AM15Spectrum(1), env);
     Scientrace.Trace trace = new Scientrace.Trace(500.0E-9, light, beam, env, 1, 1);
     Console.WriteLine(trace.ToString());
     //Scientrace.Vector v = new Scientrace.Vector(10,10,10);
     Scientrace.IntersectionPoint[] ips = new Scientrace.IntersectionPoint[2];
     ips[0] = null;
     ips[1] = null;
     //Scientrace.Intersection intr = new Scientrace.Intersection(trace, ips);
     //Assert.IsFalse(intr.intersects);
 }
Exemple #10
0
 public void TestIntersectionByVectorArray3()
 {
     Scientrace.Object3dEnvironment env = new Scientrace.Object3dEnvironment(Scientrace.AirProperties.Instance, 100);
     Scientrace.Line beam = new Scientrace.Line(10, 10, 10, -1, -1, 0);
     Scientrace.LightSource light = new Scientrace.SingleRaySource(beam,
                                                                  10, new Scientrace.AM15Spectrum(1), env);
     Scientrace.Trace trace = new Scientrace.Trace(500.0E-9, light, beam, env,1,1);
     Console.WriteLine(trace.ToString());
     //Scientrace.Vector v = new Scientrace.Vector(10,10,10);
     Scientrace.IntersectionPoint[] ips = new Scientrace.IntersectionPoint[2];
     ips[0] = null;
     ips[1] = null;
     //Scientrace.Intersection intr = new Scientrace.Intersection(trace, ips);
     //Assert.IsFalse(intr.intersects);
 }
Exemple #11
0
 public Intersection(bool intersects, Scientrace.Object3d object3d, Scientrace.Location enterloc,
                     Scientrace.FlatShape2d enterplane, Scientrace.Location exitloc, bool leaving)
 {
     this.intersects = intersects;
     this.object3d   = object3d;
     this.enter      = new IntersectionPoint(enterloc, enterplane);
     //plane of exitloc irrelevant
     if (exitloc == null)
     {
         this.exit = null;
     }
     else
     {
         this.exit = new IntersectionPoint(exitloc, null);
     }
     this.leaving = leaving;
     this.checkObject();    //<- DEBUGGING:
 }
Exemple #12
0
 public Intersection(bool intersects, Scientrace.Object3d object3d, Scientrace.Location enterloc,
                     Scientrace.FlatShape2d enterplane, Scientrace.Location exitloc)
 {
     //same as constructor above but with leaving = false.
     this.intersects = intersects;
     this.object3d   = object3d;
     this.enter      = new IntersectionPoint(enterloc, enterplane);
     if (exitloc == null)
     {
         this.exit = null;
     }
     else
     {
         this.exit = new IntersectionPoint(exitloc, null);
     }
     this.leaving = false;
     this.checkObject();    //<- DEBUGGING:
 }
Exemple #13
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)
        }
Exemple #14
0
        public override Intersection intersects(Scientrace.Trace aTrace)
        {
            // Finding intersectionpoints at sphere
            Scientrace.Intersection sphereIntersections = this.dummySphere.intersects(aTrace);

            /* If the PlanoConvexLens doesn't even pass the surface of the sphere, the intersection
             * of the lens does not exist. */
            if (!sphereIntersections.intersects)
            {
                //return sphereIntersections;
                return(Intersection.notIntersect(this));
            }

            Scientrace.Location planoLoc = this.lensPlane.lineThroughPlane(aTrace.traceline);

            Scientrace.IntersectionPoint planoIP;
            if ((!this.dummySphere.contains(planoLoc)) || (planoLoc == null))
            {
                planoIP = null;
            }
            else
            {
                planoIP = new Scientrace.IntersectionPoint(planoLoc, this.lensPlane.planeToFlatShape2d());
            }

            Scientrace.IntersectionPoint[] ips = new Scientrace.IntersectionPoint[3];
            ips[0] = planoIP;
            ips[1] = this.lensPlane.filterOutsideBorder(sphereIntersections.enter);
            ips[2] = this.lensPlane.filterOutsideBorder(sphereIntersections.exit);
            Scientrace.Intersection lensIntersection = new Scientrace.Intersection(aTrace, ips, this);

            // when currently inside the lens, intersection from here must mean leaving.
            lensIntersection.leaving = this.contains(aTrace.traceline.startingpoint);
            //return created new intersection
            return(lensIntersection);
        }
Exemple #15
0
        public override Intersection intersects(Scientrace.Trace aTrace)
        {
            // Finding intersectionpoints at sphere
            Scientrace.Intersection sphereIntersections = this.dummySphere.intersects(aTrace);
            /* If the PlanoConvexLens doesn't even pass the surface of the sphere, the intersection
               of the lens does not exist. */
            if (!sphereIntersections.intersects) {
                //return sphereIntersections;
                return Intersection.notIntersect(this);
                }

            Scientrace.Location planoLoc = this.lensPlane.lineThroughPlane(aTrace.traceline);

            Scientrace.IntersectionPoint planoIP;
            if ((!this.dummySphere.contains(planoLoc)) || (planoLoc == null)) {
                planoIP = null;
                } else {
                planoIP = new Scientrace.IntersectionPoint(planoLoc, this.lensPlane.planeToFlatShape2d());
                }

            Scientrace.IntersectionPoint[] ips = new Scientrace.IntersectionPoint[3];
            ips[0] = planoIP;
            ips[1] = this.lensPlane.filterOutsideBorder(sphereIntersections.enter);
            ips[2] = this.lensPlane.filterOutsideBorder(sphereIntersections.exit);
            Scientrace.Intersection lensIntersection = new Scientrace.Intersection(aTrace, ips, this);

            // when currently inside the lens, intersection from here must mean leaving.
            lensIntersection.leaving = this.contains(aTrace.traceline.startingpoint);
            //return created new intersection
            return lensIntersection;
        }
Exemple #16
0
 public void removeExit()
 {
     this.exit    = new IntersectionPoint(null, null);
     this.leaving = true;
 }
Exemple #17
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)
 }
Exemple #18
0
 public void initNewIntersection(Scientrace.Line traceline, Scientrace.IntersectionPoint[] ips, Scientrace.Object3d object3d, bool bothdirections)
 {
     this.object3d = object3d;
     //Console.WriteLine("New Intersection with "+ips.Length+" IP's - "+object3d.hasParent());
     this.intersects = false;
     //Console.WriteLine("FALSE");
     foreach (Scientrace.IntersectionPoint ip in ips)
     {
         if (ip == null)
         {
             //Console.WriteLine("<NULL>");
             continue;
         }
         //if bothdirections == true the Intersection does not nessicarily have to be away (in direction "direction")
         // from the startingpoint.
         if (!bothdirections)
         {
             //check if ip is in the line of the trace from its startingpoint
             if (traceline.direction.dotProduct(ip.loc - traceline.startingpoint) <= 1E-9)
             {
                 //Console.WriteLine("WARNING: Intersectionpoint "+ip.loc.ToString()+" lies in the past @ "+traceline.startingpoint);
                 continue;
             }
         }
         if (this.intersects == false)
         {
             //Console.WriteLine("TRUE");
             this.intersects = true;
             this.enter      = ip;
             this.exit       = null;       // new IntersectionPoint(null, null); CHANGED (BUGFIX?) BY JBC @ 20131205
             continue;
         }
         if (this.enter.loc.distanceTo(traceline.startingpoint) > ip.loc.distanceTo(traceline.startingpoint))
         {
             //this intersectionpoint is closer than the "enterpoint so far"
             // this condition is wrong right? if (this.exit==null) {
             this.exit = this.enter;
             // this is wrong right?     }
             this.enter = ip;
             continue;
         }
         else
         {
             if (this.exit == null)
             {
                 this.exit = ip;
                 continue;
             }
             else
             {
                 //this intersectionpoint is further from beam than enterpoint. New exitpoint defined.
                 if (this.exit.loc.distanceTo(traceline.startingpoint) > ip.loc.distanceTo(traceline.startingpoint))
                 {
                     //intersectionpoint is closer than old exitpoint
                     this.exit = ip;
                     continue;
                 }
             }
             continue;             // <-- existing exitpoint is closer than new IP: do nothing.
         }
     }
 }
        public IntersectionPoint[] intersects11circleborder(Trace trace)
        {
            Scientrace.Line line = trace.traceline;
            double d1, d2, dx, dy, lx, ly;
            double ABCa, ABCb, ABCc, discr;
            Scientrace.Vector v1, v2;
            Scientrace.FlatShape2d plane1, plane2;
            Scientrace.IntersectionPoint[] ip;
            dx = line.direction.x;
            dy = line.direction.y;
            lx = line.startingpoint.x;
            ly = line.startingpoint.y;

            ABCa = Math.Pow(ly,2)+Math.Pow(lx,2);
            ABCb = 2*((ly*dy) + (lx*dx));
            ABCc = Math.Pow(dy,2)+Math.Pow(dx,2)-1;
            discr = Math.Pow(ABCb, 2)-(4*ABCa*ABCc);
            if (discr < 0) {
            ip = new Scientrace.IntersectionPoint[0];
            //ip[0] = null;
            //ip[1] = null;
            return ip;
            }
            if (discr == 0) {
            ip = new Scientrace.IntersectionPoint[1];
            d1 = ((-ABCb)+Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa);
            v1 = (line.direction.toVector()*d1)+line.startingpoint.toVector();
                //plane1 is based on v1 rotated 90 degrees which makes: x' = -y, y' = x, z = z
            plane1 = new Scientrace.FlatShape2d(v1.toLocation(), new Scientrace.UnitVector(0,0,1),
                                                               new Scientrace.UnitVector(-v1.y, v1.x, v1.z));
            ip[0] = new IntersectionPoint(v1.toLocation(), plane1);
            return ip;
            }
            d1 = ((-ABCb)+Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa);
            d2 = ((-ABCb)-Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa);
            v1 = (line.direction.toVector()*d1)+line.startingpoint.toVector();
            v2 = (line.direction.toVector()*d2)+line.startingpoint.toVector();
            ip = new Scientrace.IntersectionPoint[2];
            plane1 = new Scientrace.FlatShape2d(v1.toLocation(), new Scientrace.UnitVector(0,0,1),
                                                               new Scientrace.UnitVector(-v1.y, v1.x, v1.z));
            ip[0] = new IntersectionPoint(v1.toLocation(), plane1);
            plane2 = new Scientrace.FlatShape2d(v2.toLocation(), new Scientrace.UnitVector(0,0,1),
                                                               new Scientrace.UnitVector(-v2.y, v2.x, v2.z));
            ip[1] = new IntersectionPoint(v2.toLocation(), plane2);
            return ip;
        }
        /* 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);
        }
        /* 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(Trace aTrace)
        {
            /* OK, this is how we are going to do this:
             * First (1), we find all intersectionpoints for all sub-borders and order them
             * as a function of the distance from the startingpoint of the trace. Then (2), we
             * take the average location in between two consecutive intersectionpoints. Let's
             * ask all SubVolumes if anybody has this average value in it's body (3). We will
             * repeat this procedure until we find an average value that is *NOT* included (4). The
             * very first intersectionpoint, and the last intersectionpoint before that latest
             * assessed average will be the two intersectionpoints construction the Intersection (5)
             * value to return.
             * A final remark must be made: when a trace is leaving from the current object and the
             * average location between the start of the trace and the first intersection is also
             * within the object, the first intersectionpoint is actually virtual and should be
             * removed. (6) */

            // (1)
            // create an orderedlist with as keys the distances from the last intersection to this ip
            SortedList<double,IntersectionPoint> all_ips = new SortedList<double,IntersectionPoint>();
            Scientrace.Location subTraceStart = aTrace.traceline.startingpoint;
            foreach (PlaneBorderEnclosedVolume aSubVolume in subVolumes) {
            Intersection tIntersection = aSubVolume.intersects(aTrace);
            if (tIntersection.intersects) {
                this.conditionalIPList(all_ips, tIntersection, subTraceStart);
                }
            }
            IntersectionPoint previous_ip = null;
            IntersectionPoint first_ip = null;
            IntersectionPoint last_ip = null;

            for (int iKey = 0; iKey < all_ips.Keys.Count; iKey++) {
            double currentKey = all_ips.Keys[iKey];
            IntersectionPoint currentIP = all_ips[currentKey];

            if (previous_ip == null) {
                // is this the last IP in the list?
                if (iKey != all_ips.Count-1) {
                    // If both the area between the start of the trace and that between this and the next trace is contained, skip to the next (by continue)
                    IntersectionPoint nextIP = all_ips[all_ips.Keys[iKey+1]];
                    if (this.contains(subTraceStart.avgWith(currentIP.loc))
                      && this.contains(currentIP.loc.avgWith(nextIP.loc))) {
                      	continue;
                        }
                    }
                // (6)
                if (this.contains(subTraceStart.avgWith(currentIP.loc)) && (iKey+1!=all_ips.Keys.Count)) {
                    first_ip = currentIP;
                    break; } else {
                    // the first ip in the list, no average to take with previous value
                    first_ip = currentIP;
                    }
                } else {
                // (2)
                Scientrace.Location average_loc = currentIP.loc.avgWith(previous_ip.loc);
                // (3)
                if (!this.contains(average_loc)) {
                    //Console.WriteLine("BREAKOUT!!!!");
                    last_ip = previous_ip;
                    // (4) Break out of foreach loop, we've found the last point in this intersection (the previous one in the list)
                    break;
                    }
                }
            // last statement in foreach loop, defining the current IP als the previous for the next cycle.
            previous_ip = currentIP;
            }

            // there has to be at least ONE intersection to succeed...
            if (first_ip == null) {
            return Intersection.notIntersect(this);
            }
            /* below must be the most obscure line in this routine, sry about that.
             * it does this: if last_ip is still unassigned, assign previous_ip as long as it differs from first_ip... */
            // last_ip = last_ip ?? (previous_ip != first_ip ? previous_ip : null);
             if (last_ip == null)
            last_ip = (previous_ip != first_ip ? previous_ip : null);
            // (5)
            Scientrace.IntersectionPoint[] real_ips = new Scientrace.IntersectionPoint[2];
            real_ips[0] = first_ip;
            real_ips[1] = last_ip;
            Intersection retIntersect = new Intersection(aTrace, real_ips, this);
            return retIntersect;
            //end func. intersect
        }
Exemple #23
0
        public override Intersection intersects(Trace aTrace)
        {
            /* OK, this is how we are going to do this:
             * First (1), we find all intersectionpoints for all sub-borders and order them
             * as a function of the distance from the startingpoint of the trace. Then (2), we
             * take the average location in between two consecutive intersectionpoints. Let's
             * ask all SubVolumes if anybody has this average value in it's body (3). We will
             * repeat this procedure until we find an average value that is *NOT* included (4). The
             * very first intersectionpoint, and the last intersectionpoint before that latest
             * assessed average will be the two intersectionpoints construction the Intersection (5)
             * value to return.
             * A final remark must be made: when a trace is leaving from the current object and the
             * average location between the start of the trace and the first intersection is also
             * within the object, the first intersectionpoint is actually virtual and should be
             * removed. (6) */

            // (1)
            // create an orderedlist with as keys the distances from the last intersection to this ip
            SortedList <double, IntersectionPoint> all_ips = new SortedList <double, IntersectionPoint>();

            Scientrace.Location subTraceStart = aTrace.traceline.startingpoint;
            foreach (PlaneBorderEnclosedVolume aSubVolume in subVolumes)
            {
                Intersection tIntersection = aSubVolume.intersects(aTrace);
                if (tIntersection.intersects)
                {
                    this.conditionalIPList(all_ips, tIntersection, subTraceStart);
                }
            }
            IntersectionPoint previous_ip = null;
            IntersectionPoint first_ip    = null;
            IntersectionPoint last_ip     = null;

            for (int iKey = 0; iKey < all_ips.Keys.Count; iKey++)
            {
                double            currentKey = all_ips.Keys[iKey];
                IntersectionPoint currentIP  = all_ips[currentKey];

                if (previous_ip == null)
                {
                    // is this the last IP in the list?
                    if (iKey != all_ips.Count - 1)
                    {
                        // If both the area between the start of the trace and that between this and the next trace is contained, skip to the next (by continue)
                        IntersectionPoint nextIP = all_ips[all_ips.Keys[iKey + 1]];
                        if (this.contains(subTraceStart.avgWith(currentIP.loc)) &&
                            this.contains(currentIP.loc.avgWith(nextIP.loc)))
                        {
                            continue;
                        }
                    }
                    // (6)
                    if (this.contains(subTraceStart.avgWith(currentIP.loc)) && (iKey + 1 != all_ips.Keys.Count))
                    {
                        first_ip = currentIP;
                        break;
                    }
                    else
                    {
                        // the first ip in the list, no average to take with previous value
                        first_ip = currentIP;
                    }
                }
                else
                {
                    // (2)
                    Scientrace.Location average_loc = currentIP.loc.avgWith(previous_ip.loc);
                    // (3)
                    if (!this.contains(average_loc))
                    {
                        //Console.WriteLine("BREAKOUT!!!!");
                        last_ip = previous_ip;
                        // (4) Break out of foreach loop, we've found the last point in this intersection (the previous one in the list)
                        break;
                    }
                }
                // last statement in foreach loop, defining the current IP als the previous for the next cycle.
                previous_ip = currentIP;
            }

            // there has to be at least ONE intersection to succeed...
            if (first_ip == null)
            {
                return(Intersection.notIntersect(this));
            }

            /* below must be the most obscure line in this routine, sry about that.
             * it does this: if last_ip is still unassigned, assign previous_ip as long as it differs from first_ip... */
            // last_ip = last_ip ?? (previous_ip != first_ip ? previous_ip : null);
            if (last_ip == null)
            {
                last_ip = (previous_ip != first_ip ? previous_ip : null);
            }
            // (5)
            Scientrace.IntersectionPoint[] real_ips = new Scientrace.IntersectionPoint[2];
            real_ips[0] = first_ip;
            real_ips[1] = last_ip;
            Intersection retIntersect = new Intersection(aTrace, real_ips, this);

            return(retIntersect);
            //end func. intersect
        }
Exemple #24
0
 public void removeExit()
 {
     this.exit = new IntersectionPoint(null,null);
     this.leaving = true;
 }
        public Scientrace.IntersectionPoint[] realIntersections(Scientrace.Line traceline, bool checkBorder)
        {
//			Scientrace.Line line = traceline-this.loc;	//substract loc value from traceline location,
            //leave direction unchanged
            //Console.WriteLine("In untransformed world: traceline -> "+traceline.ToString());
            //default value should be checkBorder = true;
            Scientrace.VectorTransform trf     = this.trf;
            Scientrace.Line            trfline = trf.transform(traceline - this.loc);
            //transform location AND direction
            Scientrace.IntersectionPoint[] ips = this.baseintersections(trfline);
            Scientrace.IntersectionPoint   tip;
            Scientrace.IntersectionPoint[] retips = new Scientrace.IntersectionPoint[2];
            for (int ipi = 0; ipi < ips.GetLength(0); ipi++)
            {
                if (ips[ipi] == null)
                {
                    retips[ipi] = null;
                    continue;
                }
                //Console.WriteLine("$$$$$$$$$$$$$$$$$"+ips[ipi].loc+"in?:"+trfline);
                //Console.WriteLine("___1");

                //check below removed for performance reasons

                /*if (!trfline.throughLocation(ips[ipi].loc, 0.00001)) {
                 *      string warning =@"ERROR: GOING DOWN! \n baseintersections "+trfline+" FAILED!";
                 *      throw new ArgumentOutOfRangeException(warning+ips[ipi].loc.trico() + " not in line " + trfline);
                 * } *///This was removed at 20160222

                /* else {
                 *      Scientrace.Line reflline = trfline.reflectAt(this.baseIntersectionPlane(ips[ipi].loc.x, ips[ipi].loc.y),0);
                 * //Console.WriteLine("___2");
                 *      /*if (!reflline.throughLocation(this.getBaseConcentrationPoint(), 0.000001)) {
                 *              //throw new ArgumentOutOfRangeException("CONCENTREER EENS!");
                 *              }*/
                //	} end of removed check
                //throw new AccessViolationException("FOO");
                //Console.WriteLine("ips["+ipi.ToString()+"]:"+ips[ipi].ToString());

                //tip = trf.transformback(ips[ipi])+this.loc;

                tip                 = ips[ipi].copy();
                tip.loc             = trf.transformback(ips[ipi].loc) + this.loc;
                tip.flatshape.plane = trf.transformback(tip.flatshape.plane);

                //Console.WriteLine("___3");

                /*if (!traceline.throughLocation(tip.loc, 0.0001)) {
                 *      throw new ArgumentOutOfRangeException(tip.loc.trico() + " (transformed) not in line " + traceline);
                 * } else {
                 *      }*/

                if (this.cborder.contains(tip.loc) || !checkBorder)          //is this location within the borders between which the
                //parabolic mirror exists?
                {
                    retips[ipi] = tip;

/*					//below for debug purposes only
 *                                      retips[ipi] = new IntersectionPoint(traceline.startingpoint+
 *                                                                          traceline.direction.toLocation()*(traceline.direction.dotProduct(tip.loc-traceline.startingpoint))
 *                                                                                                            , tip.plane);*/
                }
                else
                {
                    //Console.WriteLine(tip.loc.ToString() + " is NOT within the cborder range-> "+this.cborder);
                    retips[ipi] = null;
                    continue;
                }

                //Console.WriteLine("trf: "+trf.ToString());
                //Console.WriteLine("retips["+ipi.ToString()+"]:"+retips[ipi].ToString());
            }
            return(retips);
        }
Exemple #26
0
 public void initNewIntersection(Scientrace.Line traceline, Scientrace.IntersectionPoint[] ips, Scientrace.Object3d object3d, bool bothdirections)
 {
     this.object3d = object3d;
     //Console.WriteLine("New Intersection with "+ips.Length+" IP's - "+object3d.hasParent());
     this.intersects = false;
     //Console.WriteLine("FALSE");
     foreach (Scientrace.IntersectionPoint ip in ips) {
     if (ip == null) {
         //Console.WriteLine("<NULL>");
         continue;
     }
     //if bothdirections == true the Intersection does not nessicarily have to be away (in direction "direction")
     // from the startingpoint.
     if (!bothdirections) {
         //check if ip is in the line of the trace from its startingpoint
         if (traceline.direction.dotProduct(ip.loc-traceline.startingpoint) <= 1E-9) {
             //Console.WriteLine("WARNING: Intersectionpoint "+ip.loc.ToString()+" lies in the past @ "+traceline.startingpoint);
             continue;
             }
         }
     if (this.intersects == false) {
         //Console.WriteLine("TRUE");
         this.intersects = true;
         this.enter = ip;
         this.exit = null; // new IntersectionPoint(null, null); CHANGED (BUGFIX?) BY JBC @ 20131205
         continue;
         }
     if (this.enter.loc.distanceTo(traceline.startingpoint) > ip.loc.distanceTo(traceline.startingpoint)) {
         //this intersectionpoint is closer than the "enterpoint so far"
         // this condition is wrong right? if (this.exit==null) {
             this.exit = this.enter;
         // this is wrong right? 	}
         this.enter = ip;
         continue;
         } else {
         if (this.exit == null) {
             this.exit = ip;
             continue;
             } else {
             //this intersectionpoint is further from beam than enterpoint. New exitpoint defined.
             if (this.exit.loc.distanceTo(traceline.startingpoint) > ip.loc.distanceTo(traceline.startingpoint)) {
                 //intersectionpoint is closer than old exitpoint
                 this.exit = ip;
                 continue;
                 }}
         continue; // <-- existing exitpoint is closer than new IP: do nothing.
         }
     }
 }
        /// <summary>
        /// "line" has to be transformed so it encounters the 2nd order polynominal with
        /// its base at 0,0,0 and orientation in 0,0,1 (z-direction)
        /// </summary>
        /// <param name="line">
        /// A <see cref="Scientrace.Line"/>
        /// </param>
        public IntersectionPoint[] baseintersections(Scientrace.Line line)
        {
            // location = line.loc * (d * line.dir);
            // keep formulae readable
            double d1, d2, dx, dy, dz, c, lx, ly, lz;
            double ABCa, ABCb, ABCc, discr;

            Scientrace.Vector v1, v2;
            Scientrace.IntersectionPoint[] ip;
            c  = this.c;
            dx = line.direction.x;
            dy = line.direction.y;
            dz = line.direction.z;
            lx = line.startingpoint.x;
            ly = line.startingpoint.y;
            lz = line.startingpoint.z;

            ABCa = c * (Math.Pow(dy, 2) + Math.Pow(dx, 2));
            ABCb = (2 * c * (dy * ly + dx * lx)) - dz;
            ABCc = (c * (Math.Pow(ly, 2) + Math.Pow(lx, 2))) - lz;

            /*if ((dx*dy) == 0) {
             *      ip = new Scientrace.IntersectionPoint[1];
             *      v1 = new Vector(lx, ly, c*(Math.Pow(lx, 2)+Math.Pow(ly, 2)));
             *      ip[0] = new IntersectionPoint(v1.toLocation(), this.intersectionPlane(v1.x, v1.y));
             *      //ip[1] = null;
             *      return ip;
             * }*/
//		if ((Math.Pow(ABCa,2)) < 1E-56) { // <-- used to be
//		if ((Math.Pow(ABCa,2)) < 1E-31) { // <-- used to be
            if ((Math.Pow(ABCa, 2)) < 1E-31)      // <-- now, so no (/less) significance errors do occur any longer in results
            //Console.WriteLine("ABCa is SMALL"+ABCa.ToString());
            {
                ip    = new Scientrace.IntersectionPoint[1];
                d1    = -ABCc / ABCb;
                v1    = (line.direction.toVector() * d1) + line.startingpoint.toVector();
                ip[0] = new IntersectionPoint(v1.toLocation(), this.baseIntersectionShape(v1.x, v1.y));
                return(ip);
            }
            //Console.WriteLine("ABCa is large enough "+ABCa.ToString());

            //d1,2 => lambda 1,2 at http://amswiki.jbos.eu/wiki/index.php/Parabolic_Collision#Quadratic_formula
            //derived from the quadratic formula, note the +/- sign before the Sqrt.
            discr = Math.Pow(ABCb, 2) - (4 * ABCa * ABCc);
            if (discr < 0)
            {
                //Console.WriteLine("Negative discriminant : "+discr);
                ip = new Scientrace.IntersectionPoint[0];
                //ip[0] = null;
                //ip[1] = null;
                return(ip);
            }
            if (discr == 0)
            {
                ip    = new Scientrace.IntersectionPoint[1];
                d1    = ((-ABCb) + Math.Sqrt(Math.Pow(ABCb, 2) - (4 * ABCa * ABCc))) / (2 * ABCa);
                v1    = (line.direction.toVector() * d1) + line.startingpoint.toVector();
                ip[0] = new IntersectionPoint(v1.toLocation(), this.baseIntersectionShape(v1.x, v1.y));
                return(ip);
            }
            //still here? two results!

            /*d1 = ((-ABCb)+Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa);
            *  d2 = ((-ABCb)-Math.Sqrt(Math.Pow(ABCb, 2)-(4*ABCa*ABCc)))/(2*ABCa);*/
            d1 = ((-ABCb) + Math.Sqrt(discr)) / (2.0 * ABCa);
            d2 = ((-ABCb) - Math.Sqrt(discr)) / (2.0 * ABCa);
            v1 = (line.direction.toVector() * d1) + line.startingpoint.toVector();
            v2 = (line.direction.toVector() * d2) + line.startingpoint.toVector();


            //Console.WriteLine("discr: "+discr+" ABCa: "+ABCa+" ABCb: "+ABCb+" ABCc: "+ABCc);
            //FOR BETTER PERFORMANCE REMOVE CHECKS BELOW

            /* //This was removed at 20160222
             * if ((v1 != null) && (!line.throughLocation(v1.toLocation(), 0.00001))) {
             *      throw new Exception("TRFd line 1 "+v1.trico()+" avoids "+line.ToString());
             *      }
             * if ((v2 != null) && (!line.throughLocation(v2.toLocation(), 0.00001))) {
             *      v2 = v1;
             * //			Console.WriteLine("discr: "+discr);
             * //			throw new Exception("TRFd line 2 "+v1.trico()+" avoids "+line.ToString()+" contrairy to "+v1.trico());
             *      }
             */
            ip    = new Scientrace.IntersectionPoint[2];
            ip[0] = (v1 == null ?
                     null :
                     new IntersectionPoint(v1.toLocation(), this.baseIntersectionShape(v1.x, v1.y))
                     );
            ip[1] = (v2 == null ?
                     null :
                     new IntersectionPoint(v2.toLocation(), this.baseIntersectionShape(v2.x, v2.y))
                     );
            return(ip);
        }