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