Esempio n. 1
0
        private void CapIntersection(Ray ray, ref Intersections intersections)
        {
            if (!Closed)
            {
                return;
            }

            if (System.Math.Abs(ray.Direction.Y) < Epsilon)
            {
                return;
            }

            var t = (Minimum - ray.Origin.Y) / ray.Direction.Y;

            if (CheckCap(ray, t))
            {
                intersections.Add(new Intersection(t, this));
            }

            t = (Maximum - ray.Origin.Y) / ray.Direction.Y;
            if (CheckCap(ray, t))
            {
                intersections.Add(new Intersection(t, this));
            }
        }
Esempio n. 2
0
        protected override Intersections LocalIntersect(Ray ray)
        {
            var result = new Intersections();

            if (BoundsOf.Intersects(ray))
            {
                SavedRay = ray;

                var sphereToRay  = new Vector(ray.Origin - Point.Zero);
                var a            = ray.Direction.Dot(ray.Direction);
                var b            = 2.0 * ray.Direction.Dot(sphereToRay);
                var c            = sphereToRay.Dot(sphereToRay) - 1;
                var discriminant = b * b - 4 * a * c;

                if (discriminant < 0.0)
                {
                    return(result);
                }
                else
                {
                    result.Add(new Intersection((-b - Math.Sqrt(discriminant)) / (2 * a), this));
                    result.Add(new Intersection((-b + Math.Sqrt(discriminant)) / (2 * a), this));
                }
            }

            return(result);
        }
Esempio n. 3
0
        private void IntersectCaps(Ray ray, Intersections xs)
        {
            // caps only matter if the cone is closed, and might possibly be intersected by the ray.
            if (!Closed || Math.Abs(ray.Direction.Y) <= double.Epsilon)
            {
                return;
            }

            // check for an intersection with the lower end cap by intersecting
            // the ray with the plane at y=cone.minimum
            var t = (Minimum - ray.Origin.Y) / ray.Direction.Y;

            if (CheckCap(ray, t, Minimum))
            {
                xs.Add(new Intersection(t, this));
            }

            // check for an intersection with the upper end cap by intersecting
            // the ray with the plane at y=cone.maximum
            t = (Maximum - ray.Origin.Y) / ray.Direction.Y;
            if (CheckCap(ray, t, Maximum))
            {
                xs.Add(new Intersection(t, this));
            }
        }
Esempio n. 4
0
        protected override Intersections LocalIntersection(Ray rayTransformed)
        {
            var dir    = rayTransformed.Direction;
            var origin = rayTransformed.Origin;

            var a = dir.X * dir.X + dir.Z * dir.Z;

            if (System.Math.Abs(a) < Epsilon)
            {
                var i = new Intersections();
                CapIntersection(rayTransformed, ref i);
                return(i);
            }

            var b = 2 * origin.X * dir.X + 2 * origin.Z * dir.Z;
            var c = origin.X * origin.X + origin.Z * origin.Z - 1.0;

            var disc = b * b - 4 * a * c;

            if (disc < 0)
            {
                var i = new Intersections();
                CapIntersection(rayTransformed, ref i);
                return(i);
            }

            var t0 = (-b - System.Math.Sqrt(disc)) / (2 * a);
            var t1 = (-b + System.Math.Sqrt(disc)) / (2 * a);

            if (t0 > t1​)
            {
                var t = t1;
                t1 = t0;
                t0 = t;
            }

            var intersections = new Intersections();

            var y0 = rayTransformed.Origin.Y + t0 * rayTransformed.Direction.Y;

            if ((Minimum < y0) && (Maximum > y0))
            {
                intersections.Add(new Intersection(t0, this));
            }

            var y1 = rayTransformed.Origin.Y + t1 * rayTransformed.Direction.Y;

            if ((Minimum < y1) && (Maximum > y1))
            {
                intersections.Add(new Intersection(t1, this));
            }

            CapIntersection(rayTransformed, ref intersections);

            return(intersections);
        }
Esempio n. 5
0
        public override void IntersectLocal(ref Tuple origin, ref Tuple direction, Intersections intersections)
        {
            var dir3       = new Vector3((float)direction.X, (float)direction.Y, (float)direction.Z);
            var dirCrossE2 = Vector3.Cross(dir3, e2);
            var det        = Vector3.Dot(e1, dirCrossE2);

            if (Math.Abs(det) < Helper.Epsilon)
            {
                return;
            }

            var f          = 1.0 / det;
            var origin3    = new Vector3((float)origin.X, (float)origin.Y, (float)origin.Z);
            var p1ToOrigin = origin3 - vP1;
            var u          = f * Vector3.Dot(p1ToOrigin, dirCrossE2);

            if (u < 0 || u > 1)
            {
                return;
            }

            var originCrossE1 = Vector3.Cross(p1ToOrigin, e1);
            var v             = f * Vector3.Dot(dir3, originCrossE1);

            if (v < 0 || (u + v) > 1)
            {
                return;
            }

            var t = f * Vector3.Dot(e2, originCrossE1);

            intersections.Add(new Intersection(t, this, u, v));
        }
Esempio n. 6
0
        public Intersections Filter(Intersections xs)
        {
            // begin outside of both children
            bool inLeft  = false;
            bool inRight = false;

            // prepare a list to receive the filtered intersections
            var result = new Intersections();

            foreach (var intersection in xs)
            {
                // if i.object is part of the "left" child, then lhit is true
                bool leftHit = Left.Contains(intersection.Object);
                if (IntersectionAllowed(leftHit, inLeft, inRight))
                {
                    result.Add(intersection);
                }

                // depending on which object was hit, toggle either inl or inr
                if (leftHit)
                {
                    inLeft = !inLeft;
                }
                else
                {
                    inRight = !inRight;
                }
            }

            result.Sort();
            return(result);
        }
Esempio n. 7
0
        public void FindIntersections(Tile[,] tiles)
        {
            bool left, right, up, down;

            for (int i = 0; i < tiles.GetLength(0); i++)
            {
                for (int j = 0; j < tiles.GetLength(1); j++)
                {
                    if (tiles[i, j].label.BackColor == Color.Red)
                    {
                        continue;
                    }
                    else if (tiles[i, j].label.BackColor == Color.Green)
                    {
                        Intersections.Add(new Coord(j, i));
                        continue;
                    }

                    left  = j - 1 < 0 ? false : tiles[i, j - 1].label.BackColor == Color.White;
                    right = j + 1 > tiles.GetLength(1) ? false : tiles[i, j + 1].label.BackColor == Color.White;
                    up    = i - 1 < 0 ? false : tiles[i - 1, j].label.BackColor == Color.White;
                    down  = i + 1 > tiles.GetLength(1) ? false : tiles[i + 1, j].label.BackColor == Color.White;

                    if ((left || right) && (up || down))
                    {
                        Intersections.Add(new Coord(j, i));
                    }
                }
            }
        }
Esempio n. 8
0
 public Path(Vector start, Vector end, Intersection intersection)
 {
     Start = start;
     End   = end;
     Intersections.Add(intersection);
     Length = 0;
     CalculateDistance();
 }
Esempio n. 9
0
        public override Intersections IntersectLocal(Ray ray)
        {
            var xs = new Intersections();
            var a  = ray.Direction.X * ray.Direction.X - ray.Direction.Y * ray.Direction.Y + ray.Direction.Z * ray.Direction.Z;
            var b  = 2 * ray.Origin.X * ray.Direction.X - 2 * ray.Origin.Y * ray.Direction.Y + 2 * ray.Origin.Z * ray.Direction.Z;
            var c  = ray.Origin.X * ray.Origin.X - ray.Origin.Y * ray.Origin.Y + ray.Origin.Z * ray.Origin.Z;

            if (Math.Abs(a) <= double.Epsilon && Math.Abs(b) > double.Epsilon)
            {
                var t = -c / (2 * b);
                xs.Add(new Intersection(t, this));
            }

            if (Math.Abs(a) > double.Epsilon)
            {
                var disc = b * b - 4 * a * c;
                if (disc >= 0)
                {
                    var t0 = (-b - Math.Sqrt(disc)) / (2 * a);
                    var t1 = (-b + Math.Sqrt(disc)) / (2 * a);

                    if (t0 > t1)
                    {
                        var tmp = t0;
                        t0 = t1;
                        t1 = tmp;
                    }

                    var y0 = ray.Origin.Y + t0 * ray.Direction.Y;
                    if (Minimum < y0 && y0 < Maximum)
                    {
                        xs.Add(new Intersection(t0, this));
                    }

                    var y1 = ray.Origin.Y + t1 * ray.Direction.Y;
                    if (Minimum < y1 && y1 < Maximum)
                    {
                        xs.Add(new Intersection(t1, this));
                    }
                }
            }

            IntersectCaps(ray, xs);
            xs.Sort();
            return(xs);
        }
Esempio n. 10
0
        public override Intersections IntersectLocal(Ray ray)
        {
            var xs = new Intersections();
            var a  = ray.Direction.X * ray.Direction.X + ray.Direction.Z * ray.Direction.Z;

            // ray is not parallel to the y axis
            if (a > double.Epsilon)
            {
                var b    = 2 * ray.Origin.X * ray.Direction.X + 2 * ray.Origin.Z * ray.Direction.Z;
                var c    = ray.Origin.X * ray.Origin.X + ray.Origin.Z * ray.Origin.Z - 1;
                var disc = b * b - 4 * a * c;

                // ray does not intersect the cylinder
                if (disc < 0)
                {
                    return(xs);
                }

                var t0 = (-b - Math.Sqrt(disc)) / (2 * a);
                var t1 = (-b + Math.Sqrt(disc)) / (2 * a);

                if (t0 > t1)
                {
                    var t = t0;
                    t0 = t1;
                    t1 = t;
                }

                var y0 = ray.Origin.Y + t0 * ray.Direction.Y;
                if (Minimum < y0 && y0 < Maximum)
                {
                    xs.Add(new Intersection(t0, this));
                }

                var y1 = ray.Origin.Y + t1 * ray.Direction.Y;
                if (Minimum < y1 && y1 < Maximum)
                {
                    xs.Add(new Intersection(t1, this));
                }
            }

            IntersectCaps(ray, xs);
            xs.Sort();
            return(xs);
        }
Esempio n. 11
0
        public override void IntersectLocal(ref Tuple origin, ref Tuple direction, Intersections intersections)
        {
            var a = 2 * (direction.X * direction.X + direction.Z * direction.Z);

            // ray is not parallel to the y axis
            if (a > double.Epsilon)
            {
                var b    = 2 * (origin.X * direction.X + origin.Z * direction.Z);
                var c    = origin.X * origin.X + origin.Z * origin.Z - 1;
                var disc = b * b - 2 * a * c;

                // ray does not intersect the cylinder
                if (disc < 0)
                {
                    return;
                }

                var x    = -b / a;
                var sqrt = Math.Sqrt(disc) / a;
                var t0   = x - sqrt;
                var t1   = x + sqrt;

                if (t0 > t1)
                {
                    var t = t0;
                    t0 = t1;
                    t1 = t;
                }

                var y0 = origin.Y + t0 * direction.Y;
                if (Minimum < y0 && y0 < Maximum)
                {
                    intersections.Add(new Intersection(t0, this));
                }

                var y1 = origin.Y + t1 * direction.Y;
                if (Minimum < y1 && y1 < Maximum)
                {
                    intersections.Add(new Intersection(t1, this));
                }
            }

            IntersectCaps(new Ray(origin, direction), intersections);
        }
Esempio n. 12
0
        public override void IntersectLocal(ref Tuple origin, ref Tuple direction, Intersections intersections)
        {
            var a = direction.X * direction.X - direction.Y * direction.Y + direction.Z * direction.Z;
            var b = 2 * origin.X * direction.X - 2 * origin.Y * direction.Y + 2 * origin.Z * direction.Z;
            var c = origin.X * origin.X - origin.Y * origin.Y + origin.Z * origin.Z;

            if (Math.Abs(a) <= double.Epsilon && Math.Abs(b) > double.Epsilon)
            {
                var t = -c / (2 * b);
                intersections.Add(new Intersection(t, this));
            }

            if (Math.Abs(a) > double.Epsilon)
            {
                var disc = b * b - 4 * a * c;
                if (disc >= 0)
                {
                    var t0 = (-b - Math.Sqrt(disc)) / (2 * a);
                    var t1 = (-b + Math.Sqrt(disc)) / (2 * a);

                    if (t0 > t1)
                    {
                        var tmp = t0;
                        t0 = t1;
                        t1 = tmp;
                    }

                    var y0 = origin.Y + t0 * direction.Y;
                    if (Minimum < y0 && y0 < Maximum)
                    {
                        intersections.Add(new Intersection(t0, this));
                    }

                    var y1 = origin.Y + t1 * direction.Y;
                    if (Minimum < y1 && y1 < Maximum)
                    {
                        intersections.Add(new Intersection(t1, this));
                    }
                }
            }

            IntersectCaps(new Ray(origin, direction), intersections);
        }
Esempio n. 13
0
        public void AddPlane(Microsoft.Xna.Framework.Vector3 intersection, Microsoft.Xna.Framework.Vector3 normal)
        {
            Vector <float> p = Vector <float> .Build.Dense(new float[] { intersection.X, intersection.Y, intersection.Z });

            Vector <float> n = Vector <float> .Build.Dense(new float[] { normal.X, normal.Y, normal.Z });

            Intersections.Add(p);
            Normals.Add(n);
            qef.Add(intersection, normal);
        }
 private void InsertIntersection(Intersection intersection)
 {
     if (null == Parent)
     {
         Intersections.Add(intersection);
     }
     else
     {
         Parent.InsertIntersection(intersection);
     }
 }
Esempio n. 15
0
        public override void IntersectLocal(ref Tuple origin, ref Tuple direction, Intersections intersections)
        {
            var a            = 2 * (direction.X * direction.X + direction.Y * direction.Y + direction.Z * direction.Z);
            var b            = 2 * (direction.X * origin.X + direction.Y * origin.Y + direction.Z * origin.Z);
            var c            = origin.X * origin.X + origin.Y * origin.Y + origin.Z * origin.Z - 1;
            var discriminant = b * b - 2 * a * c;

            if (discriminant < 0)
            {
                return;
            }

            var x1      = -b / a;
            var sqrtDet = Math.Sqrt(discriminant) / a;
            var t1      = x1 - sqrtDet;
            var t2      = x1 + sqrtDet;

            intersections.Add(new Intersection(t1, this));
            intersections.Add(new Intersection(t2, this));
        }
        public Junction(int intersections, int lanes, params double[] density)
        {
            int whichLane = 0;

            for (int i = 0; i < intersections; i++)
            {
                Intersections.Add(new Intersection());
                for (int j = 0; j < lanes; j++)
                {
                    Intersections[i].Lanes.Add(new Lane());
                    Intersections[i].Lanes[^ 1].Density = density[whichLane];
Esempio n. 17
0
        public override void IntersectLocal(ref Tuple origin, ref Tuple direction, Intersections intersections)
        {
            // if ray is // to plane => no intersection
            if (Math.Abs(direction.Y) < Helper.Epsilon)
            {
                return;
            }

            var t = -origin.Y / direction.Y;

            intersections.Add(new Intersection(t, this));
        }
Esempio n. 18
0
        public override void IntersectLocal(ref Tuple origin, ref Tuple direction, Intersections intersections)
        {
            Helper.CheckAxis(origin.X, direction.X, out var xtMin, out var xtMax);
            Helper.CheckAxis(origin.Y, direction.Y, out var ytMin, out var ytMax);
            if (xtMin > ytMax || ytMin > xtMax)
            {
                return;
            }

            Helper.CheckAxis(origin.Z, direction.Z, out var ztMin, out var ztMax);

            var tMin = Math.Max(xtMin, Math.Max(ytMin, ztMin));
            var tMax = Math.Min(xtMax, Math.Min(ytMax, ztMax));

            if (tMin > tMax)
            {
                return;
            }

            intersections.Add(new Intersection(tMin, this));
            intersections.Add(new Intersection(tMax, this));
        }
Esempio n. 19
0
        private async void UpdateIntersections()
        {
            try
            {
                Logging.LogMethodCall(ClassName);
                var qf        = new QueryParameters();
                var gemStreet = GeometryEngine.Union(_selectedStreet.Value);
                qf.Geometry            = gemStreet;
                qf.SpatialRelationship = SpatialRelationship.Touches;
                var results = await FeatureSource.QueryFeaturesAsync(qf);

                Intersections.Clear();
                foreach (var result in results)
                {
                    var streetName = result.Attributes[StreetNameField].ToString();
                    if (SelectedStreet.Key == streetName)
                    {
                        continue;
                    }
                    var loc = GeometryEngine.Intersections(result.Geometry, gemStreet);
                    if (loc[0] is MapPoint)
                    {
                        Intersections.Add(new Tuple <string, Geometry>(streetName, loc[0]));
                    }
                    else if (loc[0] is Multipoint)
                    {
                        Intersections.Add(new Tuple <String, Geometry>(streetName, ((Multipoint)loc[0]).Points[0]));
                    }
                    else if (loc[0] is Multipart)
                    {
                        var geom = ((Multipart)loc[0]).Parts[0].Points[0];
                        Intersections.Add(new Tuple <string, Geometry>(streetName, geom));
                    }
                }
            }
            catch (Exception ex)
            {
                var message = "Error updating intersections";
                ErrorHelper.OnError(MethodBase.GetCurrentMethod().DeclaringType.Name, message, ex);
                Logging.LogMessage(Logging.LogType.Error, message, ex);
            }
        }
Esempio n. 20
0
        public void Add(Vector2 p, Vector2 n)
        {
            Intersections.Add(p);
            Normals.Add(n);

            /*ata.M11 += n.X * n.X;
             * ata.M12 += n.X * n.Y;
             * ata.M13 += 0; //x * z
             * ata.M21 += n.Y * n.Y;
             * ata.M22 += 0; //y * z
             * ata.M23 += 0; //z * z
             *
             * float dot = n.X * p.X + n.Y * p.Y;
             * atb.X += dot * n.X;
             * atb.Y += dot * n.Y;
             *
             * btb += dot * dot;*/

            mass_point += new Vector3(p, 0);
        }
Esempio n. 21
0
        public override void Find(IToolContext context, BaseShape shape)
        {
            var line = shape as LineShape;

            if (line == null)
            {
                throw new ArgumentNullException("shape");
            }

            if (!Settings.IsEnabled)
            {
                return;
            }

            var rectangles = context.CurrentContainer.Shapes.OfType <RectangleShape>();

            if (rectangles.Any())
            {
                foreach (var rectangle in rectangles)
                {
                    var rect          = Rect2.FromPoints(rectangle.TopLeft.ToPoint2(), rectangle.BottomRight.ToPoint2());
                    var p1            = line.StartPoint.ToPoint2();
                    var p2            = line.Point.ToPoint2();
                    var intersections = Line2.LineIntersectsWithRect(p1, p2, rect, out double x0clip, out double y0clip, out double x1clip, out double y1clip);
                    if (intersections)
                    {
                        var point1 = new PointShape(x0clip, y0clip, context.PointShape);
                        Intersections.Add(point1);
                        context.WorkingContainer.Shapes.Add(point1);
                        context.Renderer.SelectedShapes.Add(point1);

                        var point2 = new PointShape(x1clip, y1clip, context.PointShape);
                        Intersections.Add(point2);
                        context.WorkingContainer.Shapes.Add(point2);
                        context.Renderer.SelectedShapes.Add(point2);
                    }
                }
            }
        }
        public override void Find(IToolContext context, BaseShape shape)
        {
            var line = shape as LineShape;

            if (line == null)
            {
                throw new ArgumentNullException("shape");
            }

            if (!Settings.IsEnabled)
            {
                return;
            }

            var ellipses = context.CurrentContainer.Shapes.OfType <EllipseShape>();

            if (ellipses.Any())
            {
                foreach (var ellipse in ellipses)
                {
                    var            rect = Rect2.FromPoints(ellipse.TopLeft.ToPoint2(), ellipse.BottomRight.ToPoint2());
                    var            p1   = line.StartPoint.ToPoint2();
                    var            p2   = line.Point.ToPoint2();
                    IList <Point2> intersections;
                    Line2.LineIntersectsWithEllipse(p1, p2, rect, true, out intersections);
                    if (intersections != null && intersections.Any())
                    {
                        foreach (var p in intersections)
                        {
                            var point = new PointShape(p.X, p.Y, context.PointShape);
                            Intersections.Add(point);
                            context.WorkingContainer.Shapes.Add(point);
                            context.Renderer.Selected.Add(point);
                        }
                    }
                }
            }
        }
Esempio n. 23
0
        public void TestIntersectionN1N2()
        {
            var a = Sphere.Glass;

            a.Transform = Matrix.Scaling(2, 2, 2);
            a.Material.RefractiveIndex = 1.5;

            var b = Sphere.Glass;

            b.Transform = Matrix.Translation(0, 0, -0.25);
            b.Material.RefractiveIndex = 2.0;

            var c = Sphere.Glass;

            c.Transform = Matrix.Translation(0, 0, 0.25);
            c.Material.RefractiveIndex = 2.5;

            var r  = new Ray(new Point(0, 0, -4), Vector.VectorZ);
            var xs = new Intersections();

            xs.Add(new Intersection(2, a));
            xs.Add(new Intersection(2.75, b));
            xs.Add(new Intersection(3.25, c));
            xs.Add(new Intersection(4.75, b));
            xs.Add(new Intersection(5.25, c));
            xs.Add(new Intersection(6, a));

            double[,] ns = new double[, ]
            {
                { 1.0, 1.5 },
                { 1.5, 2.0 },
                { 2.0, 2.5 },
                { 2.5, 2.5 },
                { 2.5, 1.5 },
                { 1.5, 1.0 }
            };

            for (int i = 0; i < xs.Count; i++)
            {
                var comps = xs[i].PrepareComputations(r, xs);
                Assert.AreEqual(comps.N1, ns[i, 0]);
                Assert.AreEqual(comps.N2, ns[i, 1]);
            }
        }
Esempio n. 24
0
        public override void Find(IToolContext context, BaseShape shape)
        {
            var line = shape as LineShape;

            if (line == null)
            {
                throw new ArgumentNullException("shape");
            }

            if (!Settings.IsEnabled)
            {
                return;
            }

            var lines = context.CurrentContainer.Shapes.OfType <LineShape>();

            if (lines.Any())
            {
                var a0 = line.StartPoint.ToPoint2();
                var b0 = line.Point.ToPoint2();
                foreach (var l in lines)
                {
                    var    a1 = l.StartPoint.ToPoint2();
                    var    b1 = l.Point.ToPoint2();
                    Point2 clip;
                    var    intersection = Line2.LineIntersectWithLine(a0, b0, a1, b1, out clip);
                    if (intersection)
                    {
                        var point = new PointShape(clip.X, clip.Y, context.PointShape);
                        Intersections.Add(point);
                        context.WorkingContainer.Shapes.Add(point);
                        context.Renderer.SelectedShapes.Add(point);
                    }
                }
            }
        }
 /// <summary>
 /// Add intersection to the world
 /// </summary>
 public void AddIntersection(FourWayIntersection intersection) => Intersections.Add(intersection);
Esempio n. 26
0
        public override void IntersectLocal(ref Tuple origin, ref Tuple direction, Intersections intersections)
        {
            List <Tuple <double, Poly> > polynomMap = new List <Tuple <double, Poly> >();

            // tous ces calculs pourraient probablement
            // etre réduit lors d'un précalcul mais j'essaie
            // de privilégier la clarté à la rapidité pour l'instant

            double rSquare = Size * Size;

            // Cela ne sert à rien d'avoir des spheres de taille zero
            // mais soyons de bons paranoiaques tout de meme
            if (rSquare == 0.0f)
            {
                return;
            }
            double rInvSquare = 1.0f / rSquare;

            for (int i = 0; i < Points.Count; i++)
            {
                double A, B, C;
                double fDelta, t0, t1;
                Tuple  currentPoint = Points[i];

                Tuple vDist = currentPoint - origin;
                A = 1.0;
                B = -2.0 * direction.DotProduct(vDist);
                C = vDist.DotProduct(vDist);

                // on parcourt la liste des zones d'influences de la sphère courante
                // on calcule la nouvelle version du polynome qui a cours dans
                // cette zone d'influence et on le stocke de manière incrémentale
                // ce qui importe c'est la différence avec la zone précédente, ce qui permet
                // de bien gérer le cas de sphères imbriquées les unes dans les autres
                for (int j = 0; j < zoneNumber - 1; j++)
                {
                    // On calcule le Delta de l'équation s'il est négatif
                    // il n'y a pas de solution donc pas de point d'intersection
                    fDelta = B * B - 4.0f * (C - zoneTab[j].fCoef * rSquare);
                    if (fDelta < 0.0f)
                    {
                        break;
                    }

                    t0 = 0.5f * (-B - Math.Sqrt(fDelta));
                    // cool on ne s'occupe pas de l'ordre il est ici explicite t0 < t1
                    t1 = 0.5f * (-B + Math.Sqrt(fDelta));
                    Poly poly0 = new Poly
                    {
                        A = zoneTab[j].fGamma * A * rInvSquare,
                        B = zoneTab[j].fGamma * B * rInvSquare,
                        C = zoneTab[j].fGamma * C * rInvSquare + zoneTab[j].fBeta
                    };
                    Poly poly1 = new Poly {
                        A = -poly0.A, B = -poly0.B, C = -poly0.C
                    };

                    // les variations du polynome sont trièes par leur position sur le rayon
                    // au fur et à mesure qu'elles sont insérées. C'est la map qui nous garantit cela.
                    // ce serait peut-etre plus optimal de placer dans un vector sans se soucier de l'ordre
                    // et trier ensuite mais je me fiche de l'optimisation en fait.
                    polynomMap.Add(new Tuple <double, Poly>(t0, poly0));
                    polynomMap.Add(new Tuple <double, Poly>(t1, poly1));
                }
            }

            polynomMap.Sort(this);

            // en dehors de toute zone d'influence le champ de potentiel est nul
            Poly currentPolynom = new Poly {
                A = 0.0, B = 0.0, C = 0.0
            };

            double t = double.PositiveInfinity;

            for (var i = 0; i < polynomMap.Count - 1; i++)
            {
                var    kvp  = polynomMap[i];
                Poly   poly = kvp.Item2;
                double key  = kvp.Item1;

                // comme on a stocké les polynomes de manière incrémentale on
                // reconstruit le polynome de la zone d'influence courante
                currentPolynom.A += poly.A;
                currentPolynom.B += poly.B;
                currentPolynom.C += poly.C;

                double nextKey = polynomMap[i + 1].Item1;

                // ça ne sert à rien de résoudre l'équation si la zone d'influence est avant le point de départ
                // ou après le point d'arrivée sur le rayon
                if ((t > key) && nextKey > 0.01f)
                {
                    // on peut se permettre de résoudre la dernière équation de manière exacte
                    // après toutes les approximations que l'on a fait avec un nombre suffisant de découpages,
                    // il devrait être difficile de faire la distinction entre le blob et son découpage approché.
                    double fDelta = currentPolynom.B * currentPolynom.B - 4.0f * currentPolynom.A * (currentPolynom.C - 1.0f);
                    if (fDelta < 0.0f)
                    {
                        continue;
                    }

                    bool retValue = false;

                    double t0 = (0.5f / currentPolynom.A) * (-currentPolynom.B - Math.Sqrt(fDelta));
                    if ((t0 > 0.01f) && (t0 >= key) && (t0 < nextKey) && (t0 <= t))
                    {
                        t        = t0;
                        retValue = true;
                    }

                    double t1 = (0.5f / currentPolynom.A) * (-currentPolynom.B + Math.Sqrt(fDelta));
                    if ((t1 > 0.01f) && (t1 >= key) && (t1 < nextKey) && (t1 <= t))
                    {
                        t        = t1;
                        retValue = true;
                    }

                    if (retValue)
                    {
                        intersections.Add(new Intersection(t, this));
                        return;
                    }
                }
            }
        }