/// <summary> Tries to find intersection with transit walls. </summary> private static bool HasIntersectPoint(List <Wall> extrudedWalls, List <Wall> connectedSkeletonWalls, Vector2d p1, Vector2d p2, out Vector2d intersectPoint, out int transitWallIndex) { intersectPoint = new Vector2d(); transitWallIndex = -1; var distance = double.MaxValue; for (var i = 0; i < extrudedWalls.Count; i++) { var wall = extrudedWalls[i]; if (wall.IsOuter) { continue; } var start = wall.Start; var end = wall.End; double r; if (!Vector2dUtils.LineIntersects(p1, p2, start, end, out r)) { continue; } var currIntersectPoint = new Vector2d( Math.Round(p1.X + (r * (p2.X - p1.X))), Math.Round((p1.Y + (r * (p2.Y - p1.Y))))); // skip intersections of skeleton edges which are connected with footprint var skip = false; foreach (var connectedWall in connectedSkeletonWalls) { if (Vector2dUtils.LineIntersects(p1, currIntersectPoint, connectedWall.Start, connectedWall.End, out r)) { skip = true; break; } } if (skip) { continue; } if (Vector2dUtils.IsPointOnSegment(start, end, currIntersectPoint)) { var currDistance = p1.DistanceTo(currIntersectPoint); if (currDistance > 0 && currDistance < distance) { intersectPoint = currIntersectPoint; transitWallIndex = i; distance = currDistance; } } } return(transitWallIndex != -1); }
private static void InsertEntrance(InDoorGeneratorSettings settings, List <SkeletonEdge> walls, LineParametric2d ray, double minimalSideSize) { var doorEdge = default(SkeletonEdge); var distance = double.MaxValue; var intersectPoint = Vector2d.Empty; int i = -1; foreach (var edge in walls) { i++; if (edge.IsOuter && !edge.IsSkeleton) { continue; } var currIntersect = LineParametric2d.Collide(ray, edge.Line, 0.00001); if (currIntersect == Vector2d.Empty || !Vector2dUtils.IsPointOnSegment(edge.Start, edge.End, currIntersect)) { continue; } var currDistance = currIntersect.DistanceTo(ray.A); if (distance > currDistance /* && currDistance > minimalSideSize*/) { doorEdge = edge; distance = currDistance; intersectPoint = currIntersect; } } var startDist = Math.Min(distance, settings.Skeleton.Distances[doorEdge.Start]); var endDistance = Math.Min(distance, settings.Skeleton.Distances[doorEdge.End]); walls.Add(new SkeletonEdge(doorEdge.Start, intersectPoint, false, startDist, settings.HalfTransitAreaWidth)); walls.Add(new SkeletonEdge(intersectPoint, doorEdge.End, false, endDistance, settings.HalfTransitAreaWidth)); walls.Add(new SkeletonEdge(ray.A, intersectPoint, false, distance, settings.HalfTransitAreaWidth)); }