/// <summary> /// Computes the outline of a given polygon and its door lines. /// </summary> /// <param name="polygon"></param> /// <param name="doorLines"></param> /// <returns></returns> protected List <Tuple <IntVector2, bool> > GetOutline(GridPolygon polygon, List <IDoorInfo <TNode> > doorLines) { var outline = new List <Tuple <IntVector2, bool> >(); foreach (var line in polygon.GetLines()) { AddToOutline(Tuple.Create(line.From, true)); if (doorLines == null) { continue; } var doorDistances = doorLines.Select(x => new Tuple <IDoorInfo <TNode>, int>(x, Math.Min(line.Contains(x.DoorLine.From), line.Contains(x.DoorLine.To)))).ToList(); doorDistances.Sort((x1, x2) => x1.Item2.CompareTo(x2.Item2)); foreach (var pair in doorDistances) { if (pair.Item2 == -1) { continue; } var doorLine = pair.Item1.DoorLine; if (line.Contains(doorLine.From) != pair.Item2) { doorLine = doorLine.SwitchOrientation(); } doorLines.Remove(pair.Item1); AddToOutline(Tuple.Create(doorLine.From, true)); AddToOutline(Tuple.Create(doorLine.To, false)); } } return(outline); void AddToOutline(Tuple <IntVector2, bool> point) { if (outline.Count == 0) { outline.Add(point); return; } var lastPoint = outline[outline.Count - 1]; if (!lastPoint.Item2 && point.Item2 && lastPoint.Item1 == point.Item1) { return; } outline.Add(point); } }
/// <inheritdoc /> public List <IDoorLine> GetDoorPositions(GridPolygon polygon, IDoorMode doorModeRaw) { if (!(doorModeRaw is OverlapMode doorMode)) { throw new InvalidOperationException("Invalid door mode supplied"); } var lines = new List <IDoorLine>(); foreach (var line in polygon.GetLines()) { if (line.Length < 2 * doorMode.CornerDistance + doorMode.DoorLength) { continue; } lines.Add(new DoorLine(line.Shrink(doorMode.CornerDistance, doorMode.CornerDistance + doorMode.DoorLength), doorMode.DoorLength)); } return(lines); }
private DoorLine GetDoorLine(GridPolygon polygon, OrthogonalLine doorPosition) { if (doorPosition.Length == 0) { throw new InvalidOperationException(); } foreach (var side in polygon.GetLines()) { if (side.Contains(doorPosition.From) == -1 || side.Contains(doorPosition.To) == -1) { continue; } var isGoodDirection = doorPosition.From + doorPosition.Length * side.GetDirectionVector() == doorPosition.To; var from = isGoodDirection ? doorPosition.From : doorPosition.To; return(new DoorLine(new OrthogonalLine(from, from, side.GetDirection()), doorPosition.Length)); } throw new InvalidOperationException("Given door position is not on any side of the polygon"); }
private IEnumerable <IDoorLine> GetDoorLine(GridPolygon polygon, OrthogonalLine doorPosition) { var found = false; foreach (var side in polygon.GetLines()) { if (side.Contains(doorPosition.From) == -1 || side.Contains(doorPosition.To) == -1) { continue; } var isGoodDirection = doorPosition.From + doorPosition.Length * side.GetDirectionVector() == doorPosition.To; var from = isGoodDirection ? doorPosition.From : doorPosition.To; found = true; yield return(new DoorLine(new OrthogonalLine(from, from, side.GetDirection()), doorPosition.Length)); } if (found == false) { throw new InvalidOperationException("Given door position is not on any side of the polygon"); } }