Пример #1
0
        public static bool TryGetMapSideCross(Vector2 lineStart, Vector2 lineEnd, out MapSide mapSide)
        {
            mapSide = MapSide.Inside;
            if (LineIntersectsMapSide(lineStart, lineEnd, MapSide.Top))
            {
                mapSide = MapSide.Top;
                return(true);
            }

            if (LineIntersectsMapSide(lineStart, lineEnd, MapSide.Right))
            {
                mapSide = MapSide.Right;
                return(true);
            }
            if (LineIntersectsMapSide(lineStart, lineEnd, MapSide.Left))
            {
                mapSide = MapSide.Left;
                return(true);
            }
            if (LineIntersectsMapSide(lineStart, lineEnd, MapSide.Bottom))
            {
                mapSide = MapSide.Bottom;
                return(true);
            }

            return(false);
        }
Пример #2
0
        private void Clamp(MapSide mapSide)
        {
            MapSide previousMapSide    = mapSide == MapSide.Top ? MapSide.Left : (MapSide)((int)mapSide * .5f);
            MapSide nextMapSide        = mapSide == MapSide.Left ? MapSide.Top : (MapSide)((int)mapSide * 2);
            Corner  firstMapCorner     = mapCorners[(byte)((byte)mapSide + (byte)previousMapSide)];
            Corner  lastMapCorner      = mapCorners[(byte)((byte)mapSide + (byte)nextMapSide)];
            Polygon firstCornerPolygon = firstMapCorner.polygons[0];

            ;
            Polygon lastCornerPolygon = lastMapCorner.polygons[0];


            Corner  currentCorner  = firstMapCorner;
            Polygon currentPolygon = firstCornerPolygon;

            for (int i = 0; i < boundCrossingEdges[mapSide].Count; ++i)
            {
                BoundaryCrossingEdge currentBCE = boundCrossingEdges[mapSide][i];

                if (!currentBCE.isOnBorder)
                {
                    BisectEdge(currentBCE.edge, currentBCE.intersectPosition, out Corner newCorner, out VEdge oobEDge);
                    currentBCE.isOnBorder   = true;
                    currentBCE.borderCorner = newCorner;
                    CreateBorderEdge(currentCorner, newCorner, currentPolygon);

                    currentCorner = newCorner;
                }
                else
                {
                    if (currentBCE.borderCorner == null)
                    {
                        Log("IsOnBorder but no borderCorner", LogType.Exception);
                    }
                    CreateBorderEdge(currentCorner, currentBCE.borderCorner, currentPolygon);

                    currentCorner = currentBCE.borderCorner;
                }

                if (i == boundCrossingEdges[mapSide].Count - 1)
                {
                    currentPolygon = lastCornerPolygon;
                }
                else
                {
                    var            nextBCE        = boundCrossingEdges[mapSide][i + 1];
                    List <Polygon> sharedPolygons = currentBCE.edge.GetSharedPolygons(nextBCE.edge);
                    if (sharedPolygons.Count != 1)
                    {
                        Log("Unusual shared polygon count: " + sharedPolygons.Count
                            + "\nedge: " + currentBCE.edge.id + " Next edge: " + nextBCE.edge.id, LogType.Exception);
                    }

                    currentPolygon = sharedPolygons[0];
                }
            }

            CreateBorderEdge(currentCorner, lastMapCorner, currentPolygon);
        }
Пример #3
0
        private Dictionary <MapSide, List <BoundaryCrossingEdge> > GetBoundCrossingEdges()
        {
            List <Corner> foundBorderCorners = new List <Corner>();

            // List semi-oob edges with the intersection point
            Dictionary <MapSide, List <BoundaryCrossingEdge> > crossingEdges
                = new Dictionary <MapSide, List <BoundaryCrossingEdge> >();

            crossingEdges[MapSide.Left]   = new List <BoundaryCrossingEdge>();
            crossingEdges[MapSide.Right]  = new List <BoundaryCrossingEdge>();
            crossingEdges[MapSide.Bottom] = new List <BoundaryCrossingEdge>();
            crossingEdges[MapSide.Top]    = new List <BoundaryCrossingEdge>();

            foreach (var edge in uniqueVEdges)             // !!Need to get corners on border too!!
            {
                if (TryGetBoundsIntersections(edge, out Dictionary <MapSide, List <Vector2> > intersections, out List <Corner> borderCorners))
                {
                    bool isCornerCutter = false;
                    if (intersections.Count == 2)
                    {
                        isCornerCutter = true;
                    }

                    if (borderCorners.Count != 0)
                    {
                        if (isCornerCutter && TryGetCornerOOBofSameSideAs(borderCorners[0].position, edge, out Corner sameSideCorner, out MapSide mapSide))
                        {                         // skip this edge. It may give us invalid polygon results later.
                            Log("Ignoring edge: " + edge.id + " corner: " + sameSideCorner.num);
                            debugEdges.Add(edge);
                            intersections.Remove(mapSide);
                        }
                        else
                        {
                            foreach (var corner in borderCorners)
                            {
                                MapSide side = GetOnBorderMapSide(corner);
                                intersections.Remove(side);
                                // if not corner cutter, Remove(side) will remove both intersections....which is maybe what we want?

                                if (!foundBorderCorners.Contains(corner))
                                {
                                    foundBorderCorners.Add(corner);
                                    crossingEdges[side].Add(new BoundaryCrossingEdge(edge, corner.position, true, isCornerCutter, corner));
                                }
                            }
                        }
                    }


                    foreach (var kvp in intersections)
                    {
                        crossingEdges[kvp.Key].Add(new BoundaryCrossingEdge(edge, kvp.Value[0], false, isCornerCutter));
                    }
                }
            }
Пример #4
0
        public static bool LineIntersectsMapSide(Vector2 lineStart, Vector2 lineEnd, MapSide mapSide)
        {
            switch (mapSide)
            {
            case MapSide.Top:
                return(TryGetLineIntersection(topRight, topLeft, lineStart, lineEnd, out Vector2 top));

            case MapSide.Right:
                return(TryGetLineIntersection(bottomRight, topRight, lineStart, lineEnd, out Vector2 right));

            case MapSide.Bottom:
                return(TryGetLineIntersection(bottomLeft, bottomRight, lineStart, lineEnd, out Vector2 bottom));

            case MapSide.Left:
                return(TryGetLineIntersection(topLeft, bottomLeft, lineStart, lineEnd, out Vector2 left));
            }

            return(false);
        }
Пример #5
0
 /// <summary>
 /// Extracts a track map from the data.
 /// </summary>
 /// <param name="data">the input data; can be an array of microtracks, a linked zone or a TotalScan volume.</param>
 /// <param name="side">the side to be used.</param>
 /// <param name="r">the rectangle that sets the bounds for the track map to be extracted.</param>
 /// <param name="flt">the track filter; leave <c>null</c> to skip filtering.</param>
 /// <param name="useoriginal">if <c>true</c>, the original (anti-transformed) tracks are used; ignored if the input data is other than a TotalScan volume.</param>
 /// <returns>the subset of tracks to be used for mapping.</returns>
 public static SySal.Tracking.MIPEmulsionTrackInfo[] ExtractMap(object data, MapSide side, SySal.BasicTypes.Rectangle r, dMapFilter flt, bool useoriginal)
 {
     if (data is SySal.Scanning.Plate.LinkedZone)
     {
         return(lzExtractMap((SySal.Scanning.Plate.LinkedZone)data, side, r, flt));
     }
     else if (data is SySal.TotalScan.Layer)
     {
         int s = ((SySal.TotalScan.Layer)data).Side;
         if (s != (int)side)
         {
             throw new Exception("Expected side = " + side + " but found " + s + ".");
         }
         return(layExtractMap((SySal.TotalScan.Layer)data, r, flt, useoriginal));
     }
     else if (data is SySal.Tracking.MIPEmulsionTrackInfo[])
     {
         return(tkExtractMap((SySal.Tracking.MIPEmulsionTrackInfo[])data, r, flt));
     }
     throw new Exception("Map extraction from type " + data.GetType() + " is not supported.");
 }
Пример #6
0
        public static bool TryGetCornerOOBofSameSideAs(Vector2 borderCoord, VEdge edge, out Corner sameSideCorner, out MapSide mapSide)
        {
            mapSide = GetOnBorderMapSide(borderCoord);
            float lockedCoord = 0;

            switch (mapSide)
            {
            case MapSide.Left:

                lockedCoord = topLeft.x;
                if (edge.start.position.y > lockedCoord)
                {
                    sameSideCorner = edge.start;
                }
                else
                {
                    sameSideCorner = edge.end;
                }
                return(true);

            case MapSide.Right:
                lockedCoord = topRight.x;
                if (edge.start.position.x > lockedCoord)
                {
                    sameSideCorner = edge.start;
                }
                else
                {
                    sameSideCorner = edge.end;
                }
                return(true);

            case MapSide.Bottom:
                lockedCoord = bottomRight.y;
                if (edge.start.position.y < lockedCoord)
                {
                    sameSideCorner = edge.start;
                }
                else
                {
                    sameSideCorner = edge.end;
                }
                return(true);

            case MapSide.Top:
                lockedCoord = topLeft.y;
                if (edge.start.position.x < lockedCoord)
                {
                    sameSideCorner = edge.start;
                }
                else
                {
                    sameSideCorner = edge.end;
                }
                return(true);
            }

            sameSideCorner = null;
            return(false);
        }
Пример #7
0
        static SySal.Tracking.MIPEmulsionTrackInfo[] lzExtractMap(SySal.Scanning.Plate.LinkedZone lz, MapSide side, SySal.BasicTypes.Rectangle r, dMapFilter flt)
        {
            System.Collections.ArrayList ar = new System.Collections.ArrayList();
            int n;

            switch (side)
            {
            case MapSide.Base: n = lz.Length; break;

            case MapSide.Top: n = lz.Top.Length; break;

            case MapSide.Bottom: n = lz.Bottom.Length; break;

            default: throw new Exception("Internal inconsistency: side = " + side + " is not supported.");
            }
            int i;

            for (i = 0; i < n; i++)
            {
                SySal.Tracking.MIPEmulsionTrackInfo info;
                switch (side)
                {
                case MapSide.Base: info = lz[i].Info; break;

                case MapSide.Top: info = lz.Top[i].Info; break;

                case MapSide.Bottom: info = lz.Bottom[i].Info; break;

                default: throw new Exception("Internal inconsistency: side = " + side + " is not supported.");
                }
                if (info.Intercept.X < r.MinX || info.Intercept.X > r.MaxX || info.Intercept.Y < r.MinY || info.Intercept.Y > r.MaxY)
                {
                    continue;
                }
                if (flt == null || flt(info))
                {
                    ar.Add(info);
                }
            }
            return((SySal.Tracking.MIPEmulsionTrackInfo[])ar.ToArray(typeof(SySal.Tracking.MIPEmulsionTrackInfo)));
        }