Пример #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);
            }
        }
Пример #2
0
        public Vertex(Vector2d point, double distance, LineParametric2d bisector,
                      Edge previousEdge, Edge nextEdge)
        {
            Point        = point;
            Distance     = Math.Round(distance, RoundDigitCount);
            Bisector     = bisector;
            PreviousEdge = previousEdge;
            NextEdge     = nextEdge;

            IsProcessed = false;
        }
Пример #3
0
        public static Vector2d Collide(LineParametric2d ray, LineLinear2d line, double epsilon)
        {
            var collide = LineLinear2d.Collide(ray.CreateLinearForm(), line);

            if (collide.Equals(Vector2d.Empty))
            {
                return(Vector2d.Empty);
            }

            var collideVector = collide - ray.A;

            return(ray.U.Dot(collideVector) < epsilon ? Vector2d.Empty : collide);
        }
Пример #4
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));
        }
Пример #5
0
        public static bool IsPointOnRay(Vector2d point, LineParametric2d ray, double epsilon)
        {
            var rayDirection = new Vector2d(ray.U).Normalized();
            // test if point is on ray
            var pointVector = point - ray.A;

            var dot = rayDirection.Dot(pointVector);

            if (dot < epsilon)
            {
                return(false);
            }

            var x = rayDirection.X;

            rayDirection.X = rayDirection.Y;
            rayDirection.Y = -x;

            dot = rayDirection.Dot(pointVector);

            return(-epsilon < dot && dot < epsilon);
        }
Пример #6
0
        /// <summary>
        ///     Calculate intersection points for rays. It can return more then one
        ///     intersection point when rays overlaps.
        ///     <see href="http://geomalgorithms.com/a05-_intersect-1.html" />
        ///     <see href="http://softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm" />
        /// </summary>
        /// <returns>class with intersection points. It never return null.</returns>
        public static IntersectPoints IntersectRays2D(LineParametric2d r1, LineParametric2d r2)
        {
            var s1p0 = r1.A;
            var s1p1 = r1.A + r1.U;

            var s2p0 = r2.A;

            var u = r1.U;
            var v = r2.U;

            var w = s1p0 - s2p0;
            var d = Perp(u, v);

            // test if they are parallel (includes either being a point)
            if (Math.Abs(d) < SmallNum)
            {
                // they are NOT collinear
                // S1 and S2 are parallel
                if (Perp(u, w) != 0 || Perp(v, w) != 0)
                {
                    return(Empty);
                }

                // they are collinear or degenerate
                // check if they are degenerate points
                var du = Dot(u, u);
                var dv = Dot(v, v);
                if (du == 0 && dv == 0)
                {
                    // both segments are points
                    if (s1p0 != s2p0)
                    {
                        return(Empty);
                    }

                    // they are the same point
                    return(new IntersectPoints(s1p0));
                }
                if (du == 0)
                {
                    // S1 is a single point
                    if (!InCollinearRay(s1p0, s2p0, v))
                    {
                        return(Empty);
                    }

                    return(new IntersectPoints(s1p0));
                }
                if (dv == 0)
                {
                    // S2 a single point
                    if (!InCollinearRay(s2p0, s1p0, u))
                    {
                        return(Empty);
                    }

                    return(new IntersectPoints(s2p0));
                }
                // they are collinear segments - get overlap (or not)
                double t0, t1;
                // endpoints of S1 in eqn for S2
                var w2 = s1p1 - s2p0;
                if (v.X != 0)
                {
                    t0 = w.X / v.X;
                    t1 = w2.X / v.X;
                }
                else
                {
                    t0 = w.Y / v.Y;
                    t1 = w2.Y / v.Y;
                }
                if (t0 > t1)
                {
                    // must have t0 smaller than t1
                    var t = t0;
                    t0 = t1;
                    t1 = t; // swap if not
                }
                if (t1 < 0)
                {
                    // NO overlap
                    return(Empty);
                }

                // clip to min 0
                t0 = t0 < 0 ? 0 : t0;

                if (t0 == t1)
                {
                    // intersect is a point
                    var I0 = new Vector2d(v);
                    I0 *= t0;
                    I0 += s2p0;

                    return(new IntersectPoints(I0));
                }

                // they overlap in a valid subsegment

                // I0 = S2_P0 + t0 * v;
                var I_0 = new Vector2d(v);
                I_0 *= t0;
                I_0 += s2p0;

                // I1 = S2_P0 + t1 * v;
                var I1 = new Vector2d(v);
                I1 *= t1;
                I1 += s2p0;

                return(new IntersectPoints(I_0, I1));
            }

            // the segments are skew and may intersect in a point
            // get the intersect parameter for S1
            var sI = Perp(v, w) / d;

            if (sI < 0 /* || sI > 1 */)
            {
                return(Empty);
            }

            // get the intersect parameter for S2
            var tI = Perp(u, w) / d;

            if (tI < 0 /* || tI > 1 */)
            {
                return(Empty);
            }

            // I0 = S1_P0 + sI * u; // compute S1 intersect point
            var IO = new Vector2d(u);

            IO *= sI;
            IO += s1p0;

            return(new IntersectPoints(IO));
        }