Example #1
0
        private static void InsertEntrances(InDoorGeneratorSettings settings, Floor floor,
                                            List <SkeletonEdge> walls)
        {
            var footprint = settings.Footprint;

            // doors are not set
            if (settings.Doors == null)
            {
                FindDoorPosition(settings);
            }

            foreach (var door in settings.Doors)
            {
                var start = footprint[door.Key];
                var end   = footprint[(door.Key + 1) % footprint.Count];

                var centerOffset = door.Value;
                var vec          = (end - start).Normalized();
                var startOfDoor  = start + vec * (centerOffset - settings.HalfTransitAreaWidth);
                var endOfDoor    = start + vec * (centerOffset + settings.HalfTransitAreaWidth);
                floor.Entrances.Add(new LineSegment2d(startOfDoor, endOfDoor));

                var centerOfDoor = start + vec * centerOffset;
                vec.Negate();
                var doorRay = new LineParametric2d(centerOfDoor, Vector2dUtils.OrthogonalRight(vec));
                InsertEntrance(settings, walls, doorRay, centerOffset + settings.HalfTransitAreaWidth);
            }
        }
        private void DetectIntersectSegments(List <Vector2d> footprint, Vector2d start, Vector2d end,
                                             out Vector2d first, out int firstIndex, out Vector2d second, out int secondIndex)
        {
            firstIndex  = -1;
            secondIndex = -1;
            first       = default(Vector2d);
            second      = default(Vector2d);
            for (int i = 0; i < footprint.Count; i++)
            {
                var p1 = footprint[i];
                var p2 = footprint[i == footprint.Count - 1 ? 0 : i + 1];

                double r;
                if (Vector2dUtils.LineIntersects(start, end, p1, p2, out r))
                {
                    var intersectionPoint = Vector2dUtils.GetPointAlongLine(p1, p2, r);
                    if (firstIndex == -1)
                    {
                        firstIndex = i;
                        first      = intersectionPoint;
                    }
                    else
                    {
                        secondIndex = i;
                        second      = intersectionPoint;
                        break;
                    }
                }
            }
        }
Example #3
0
        /// <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 void FillMeshData(MeshData meshData, GradientWrapper gradient, float roofOffset, float roofHeight,
                                  List <Vector2d> footprint, Vector2d first, int firstIndex, Vector2d second, int secondIndex)
        {
            var      meshIndex       = (MultiPlaneMeshIndex)meshData.Index;
            var      count           = footprint.Count;
            int      i               = secondIndex;
            Vector2d startRidgePoint = default(Vector2d);

            do
            {
                var p1 = footprint[i];
                var p2 = footprint[i == footprint.Count - 1 ? 0 : i + 1];

                var nextIndex = i == count - 1 ? 0 : i + 1;
                // front faces
                if (i == firstIndex || i == secondIndex)
                {
                    startRidgePoint = i == firstIndex ? first : second;
                    var v0 = new Vector3((float)p1.X, roofOffset, (float)p1.Y);
                    var v1 = new Vector3((float)startRidgePoint.X, roofHeight, (float)startRidgePoint.Y);
                    var v2 = new Vector3((float)p2.X, roofOffset, (float)p2.Y);
                    meshIndex.AddPlane(v0, v1, v2, meshData.NextIndex);
                    AddTriangle(meshData, gradient, v0, v1, v2);
                    i = nextIndex;
                    continue;
                }
                // side faces
                Vector2d endRidgePoint;
                if (nextIndex == firstIndex || nextIndex == secondIndex)
                {
                    endRidgePoint = nextIndex == firstIndex ? first : second;
                }
                else
                {
                    endRidgePoint = Vector2dUtils.GetPointOnLine(first, second, p2);
                }

                // add trapezoid
                {
                    var v0 = new Vector3((float)p1.X, roofOffset, (float)p1.Y);
                    var v1 = new Vector3((float)p2.X, roofOffset, (float)p2.Y);
                    var v2 = new Vector3((float)endRidgePoint.X, roofHeight, (float)endRidgePoint.Y);
                    var v3 = new Vector3((float)startRidgePoint.X, roofHeight, (float)startRidgePoint.Y);

                    meshIndex.AddPlane(v0, v1, v2, meshData.NextIndex);
                    AddTriangle(meshData, gradient, v0, v2, v1);
                    AddTriangle(meshData, gradient, v2, v0, v3);
                }
                startRidgePoint = endRidgePoint;
                i = nextIndex;
            } while (i != secondIndex);
        }
Example #5
0
        public void CanDetectIntersection()
        {
            // ARRANGE
            var    s1 = new Vector2d(0, 0);
            var    e1 = new Vector2d(10, 10);
            var    s2 = new Vector2d(10, 0);
            var    e2 = new Vector2d(0, 10);
            double r;

            // ACT
            var result             = Vector2dUtils.LineIntersects(s1, e1, s2, e2, out r);
            var currIntersectPoint = Vector2dUtils.GetPointAlongLine(s1, s2, r);

            // ASSERT
            Assert.IsTrue(result);
            Assert.IsTrue(Math.Abs(currIntersectPoint.X - 5) < MathUtils.Epsion);
            Assert.IsTrue(Math.Abs(currIntersectPoint.X - 5) < MathUtils.Epsion);
        }
Example #6
0
        /// <summary>
        ///     Inserts Vertical Access Area (VAA): stairs, elevators, etc.
        ///     and merges it with corridors.
        /// </summary>
        private static List <List <IntPoint> > CreateTransitArea(InDoorGeneratorSettings settings,
                                                                 Floor floor, List <SkeletonEdge> walls, List <List <IntPoint> > transitPolygons)
        {
            foreach (var wall in walls)
            {
                if (wall.Size - settings.TransitAreaWidth > settings.VaaSizeWidth &&
                    wall.Distance > settings.VaaSizeHeight)
                {
                    var startOfVaa1 = wall.Start + (wall.End - wall.Start).Normalized() * settings.HalfTransitAreaWidth;

                    var orthogonalLeft = Vector2dUtils.OrthogonalLeft(wall.Start - wall.End).Normalized();
                    var endOfVaa1      = startOfVaa1 + orthogonalLeft * settings.VaaSizeHeight;
                    var startOfVaa2    = startOfVaa1 + (wall.End - startOfVaa1).Normalized() * settings.VaaSizeWidth;
                    var endOfVaa2      = startOfVaa2 + orthogonalLeft * settings.VaaSizeHeight;

                    settings.Clipper.AddPath(new List <IntPoint>
                    {
                        new IntPoint(startOfVaa1.X * Scale, startOfVaa1.Y * Scale),
                        new IntPoint(endOfVaa1.X * Scale, endOfVaa1.Y * Scale),
                        new IntPoint(endOfVaa2.X * Scale, endOfVaa2.Y * Scale),
                        new IntPoint(startOfVaa2.X * Scale, startOfVaa2.Y * Scale)
                    }, PolyType.ptClip, true);

                    floor.Stairs.Add(startOfVaa1);
                    floor.Stairs.Add(endOfVaa1);
                    floor.Stairs.Add(endOfVaa2);
                    floor.Stairs.Add(startOfVaa2);

                    break;
                }
            }

            settings.Clipper.AddPaths(transitPolygons, PolyType.ptSubject, true);
            var transitArea = new List <List <IntPoint> >(1);

            settings.Clipper.Execute(ClipType.ctUnion, transitArea);
            settings.Clipper.Clear();

            return(transitArea);
        }
Example #7
0
        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));
        }
        public bool IsOnRightSite(Vector2d point, double epsilon)
        {
            var direction = point - A;

            return(Vector2dUtils.OrthogonalRight(U).Dot(direction) > -epsilon);
        }