private List <Tuple <Vector2Int, bool> > GetOutlineOld(PolygonGrid2D polygon, List <OrthogonalLineGrid2D> doorLines) { var outline = new List <Tuple <Vector2Int, bool> >(); doorLines = doorLines?.ToList(); foreach (var line in polygon.GetLines()) { AddToOutline(Tuple.Create(line.From, true)); if (doorLines == null) { continue; } var doorDistances = doorLines.Select(x => new Tuple <OrthogonalLineGrid2D, int>(x, Math.Min(line.Contains(x.From), line.Contains(x.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; 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 <Vector2Int, 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 <DoorLineGrid2D> GetDoors(PolygonGrid2D roomShape) { var lines = new List <DoorLineGrid2D>(); foreach (var line in roomShape.GetLines()) { if (line.Length < 2 * CornerDistance + DoorLength) { continue; } lines.Add(new DoorLineGrid2D(line.Shrink(CornerDistance, CornerDistance + DoorLength), DoorLength, DoorSocket)); } return(lines); }
/// <inheritdoc /> public List <DoorLine> GetDoorPositions(PolygonGrid2D polygon, IDoorMode doorModeRaw) { if (!(doorModeRaw is SimpleDoorMode doorMode)) { throw new InvalidOperationException("Invalid door mode supplied"); } var lines = new List <DoorLine>(); 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 IEnumerable <DoorLine> GetDoorLine(PolygonGrid2D polygon, OrthogonalLineGrid2D 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 OrthogonalLineGrid2D(from, from, side.GetDirection()), doorPosition.Length)); } if (found == false) { throw new ArgumentException($"The door line {doorPosition.ToStringShort()} is not on the outline of the polygon {polygon}. Make sure that all the door lines of a manual door mode are on the outline of the polygon."); } }
private List <OutlineSegment> GetOutlineNew(PolygonGrid2D polygon, List <LayoutDoorGrid2D <TNode> > doorLines = null, Vector2Int offset = default) { var old = GetOutline(polygon, doorLines); var outline = new List <OutlineSegment>(); if (doorLines == null) { foreach (var line in polygon.GetLines()) { outline.Add(new OutlineSegment(line + offset, false)); } } else { for (int i = 0; i < old.Count; i++) { var current = old[i]; var previous = old[Mod(i - 1, old.Count)]; outline.Add(new OutlineSegment(new OrthogonalLineGrid2D(previous.Item1 + offset, current.Item1 + offset), current.Item2 == false)); } } return(outline); }
private void DrawHatching(PolygonGrid2D outline) { var pen = new Pen(Color.FromArgb(50, 50, 50), scale * 0.55f); graphics.SmoothingMode = SmoothingMode.HighQuality; var usedPointsAdd = new List <Vector2>(); foreach (var line in outline.GetLines()) { var points = line.GetPoints().Select(x => (Vector2)x).ToList(); points.AddRange(points.Select(x => x + 0.5f * (Vector2)line.GetDirectionVector()).ToList()); for (var i = 0; i < points.Count; i++) { var point = points[i]; if (true) { var direction = (Vector2)line.GetDirectionVector(); var directionPerpendicular = new Vector2(Math.Max(-1, Math.Min(1, direction.Y)), Math.Max(-1, Math.Min(1, direction.X))); if (direction.Y != 0) { directionPerpendicular = -1 * directionPerpendicular; } for (int j = 0; j < 2; j++) { var rotation = random.Next(0, 366); var offsetLength = scale * NextFloat(2, 4) * 1.75f; var clusterOffset = scale * NextFloat(1.5f, 3f); if (j == 1) { offsetLength = 0; } var c = point + offsetLength * directionPerpendicular; if (usedPoints.Any(x => Vector2.EuclideanDistance(x, c) < scale * 5)) { continue; } else { usedPointsAdd.Add(c); } for (int k = -1; k <= 1; k++) { var length = scale * 3; var center = point + offsetLength * directionPerpendicular + k * clusterOffset * directionPerpendicular; center = RotatePoint(center, point + offsetLength * directionPerpendicular, rotation); var from = center + length * direction; var to = center - length * direction; from = RotatePoint(from, center, rotation); to = RotatePoint(to, center, rotation); graphics.DrawLine(pen, from.X, from.Y, to.X, to.Y); } } } } } usedPoints.AddRange(usedPointsAdd); }
protected void DrawHatching(PolygonGrid2D outline, List <Tuple <RectangleGrid2D, List <Vector2> > > usedPoints, Range <float> hatchingClusterOffset, Range <float> hatchingLength) { var pen = new Pen(Color.FromArgb(50, 50, 50), 0.05f); var usedPointsAdd = new List <Vector2>(); foreach (var line in outline.GetLines()) { var points = line.GetPoints().Select(x => (Vector2)x).ToList(); points.AddRange(points.Select(x => x + 0.5f * (Vector2)line.GetDirectionVector()).ToList()); for (var i = 0; i < points.Count; i++) { var point = points[i]; if (true) { var direction = (Vector2)line.GetDirectionVector(); var directionPerpendicular = new Vector2(Math.Max(-1, Math.Min(1, direction.Y)), Math.Max(-1, Math.Min(1, direction.X))); if (direction.Y != 0) { directionPerpendicular = -1 * directionPerpendicular; } for (int j = 0; j < 2; j++) { var rotation = random.Next(0, 366); var offsetLength = NextFloat(2, 4) * 1.75f / 10; var clusterOffset = GetRandomFromRange(hatchingClusterOffset); if (j == 1) { offsetLength = 0; } var c = point + offsetLength * directionPerpendicular; // TODO: very ugly if (usedPoints.Any(x => Vector2.MaxDistance(x.Item1.Center, c) < Math.Max(x.Item1.Width, x.Item1.Height) + 5 && x.Item2.Any(y => Vector2.EuclideanDistance(y, c) < 0.5f))) { continue; } else { usedPointsAdd.Add(c); } for (int k = -1; k <= 1; k++) { var length = GetRandomFromRange(hatchingLength); var center = point + offsetLength * directionPerpendicular + k * clusterOffset * directionPerpendicular; center = RotatePoint(center, point + offsetLength * directionPerpendicular, rotation); var from = center + length / 2 * direction; var to = center - length / 2 * direction; from = RotatePoint(from, center, rotation); to = RotatePoint(to, center, rotation); graphics.DrawLine(pen, from.X, from.Y, to.X, to.Y); } } } } } usedPoints.Add(new Tuple <RectangleGrid2D, List <Vector2> >(outline.BoundingRectangle, usedPointsAdd)); }