Example #1
0
        /// <summary>
        /// Check and return polygon intersections
        /// </summary>
        /// <param name="polygon1"></param>
        /// <param name="polygon2"></param>
        /// <param name="intersections"></param>
        /// <returns></returns>
        private static bool VerticesIntersect(Vertices polygon1, Vertices polygon2,
                                              out List <EdgeIntersectInfo> intersections)
        {
            intersections = new List <EdgeIntersectInfo>();

            // Iterate through polygon1's edges
            for (int i = 0; i < polygon1.Count; i++)
            {
                // Get edge vertices
                Vector2 p1 = polygon1[i];
                Vector2 p2 = polygon1[polygon1.NextIndex(i)];

                // Get intersections between this edge and polygon2
                for (int j = 0; j < polygon2.Count; j++)
                {
                    Vector2 point;

                    Vector2 p3 = polygon2[j];
                    Vector2 p4 = polygon2[polygon2.NextIndex(j)];

                    // Check if the edges intersect
                    if (LineTools.LineIntersect(p1, p2, p3, p4, true, true, out point))
                    {
                        // Here, we round the returned intersection point to its nearest whole number.
                        // This prevents floating point anomolies where 99.9999-> is returned instead of 100.
                        point = new Vector2((float)Math.Round(point.X, 0), (float)Math.Round(point.Y, 0));
                        // Record the intersection
                        intersections.Add(new EdgeIntersectInfo(new Edge(p1, p2), new Edge(p3, p4), point));
                    }
                }
            }

            // true if any intersections were found.
            return(intersections.Count > 0);
        }
Example #2
0
        private bool SearchForOutstandingVertex(Vertices hullArea, out Vector2 outstanding)
        {
            Vector2 outstandingResult = Vector2.Zero;
            bool    found             = false;

            if (hullArea.Count > 2)
            {
                int hullAreaLastPoint = hullArea.Count - 1;

                Vector2 tempVector1;
                Vector2 tempVector2 = hullArea[0];
                Vector2 tempVector3 = hullArea[hullAreaLastPoint];

                // Search between the first and last hull point.
                for (int i = 1; i < hullAreaLastPoint; i++)
                {
                    tempVector1 = hullArea[i];

                    // Check if the distance is over the one that's tolerable.
                    if (LineTools.DistanceBetweenPointAndLineSegment(ref tempVector1, ref tempVector2, ref tempVector3) >= _hullTolerance)
                    {
                        outstandingResult = hullArea[i];
                        found             = true;
                        break;
                    }
                }
            }

            outstanding = outstandingResult;
            return(found);
        }
Example #3
0
        private static bool CanSee(int i, int j, Vertices vertices)
        {
            if (Reflex(i, vertices))
            {
                if (LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)) &&
                    RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)))
                {
                    return(false);
                }
            }
            else
            {
                if (RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)) ||
                    LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)))
                {
                    return(false);
                }
            }

            if (Reflex(j, vertices))
            {
                if (LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)) &&
                    RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)))
                {
                    return(false);
                }
            }
            else
            {
                if (RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)) ||
                    LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)))
                {
                    return(false);
                }
            }

            for (int k = 0; k < vertices.Count; ++k)
            {
                if ((k + 1) % vertices.Count == i || k == i || (k + 1) % vertices.Count == j || k == j)
                {
                    continue;                     // ignore incident edges
                }

                Vector2 intersectionPoint;

                if (LineTools.LineIntersect(At(i, vertices), At(j, vertices), At(k, vertices), At(k + 1, vertices),
                                            out intersectionPoint))
                {
                    return(false);
                }
            }

            return(true);
        }
        public static Option Registration()
        {
            ConsoleWriter.ClearScreen();
            var lines     = File.ReadAllLines(@"UI/maps/4a.Registration.txt");
            var drawables = TextEditor.Add.DrawablesAt(lines, 0);

            TextEditor.Center.AllUnitsInXDir(drawables, Console.WindowWidth);
            TextEditor.Center.InYDir(drawables, Console.WindowHeight);
            ConsoleWriter.TryAppend(drawables);
            ConsoleWriter.Update();

            Func <IDrawable, (int X, int Y)> getCoord = drawable => (drawable.CoordinateX + 2, drawable.CoordinateY);

            var colons = drawables.FindAll(x => x.Chars == ":");

            var nameCoord  = getCoord(colons[0]);
            var pass1Coord = getCoord(colons[1]);
            var pass2Coord = getCoord(colons[2]);

            Console.ForegroundColor = ConsoleColor.Green;
            LineTools.SetCursor(nameCoord);

            var nameLine  = new InputLine(nameCoord.X, nameCoord.Y, 30, ConsoleColor.Green);
            var pass1Line = new InputLine(pass1Coord.X, pass1Coord.Y, 30, ConsoleColor.Green);
            var pass2Line = new InputLine(pass2Coord.X, pass2Coord.Y, 30, ConsoleColor.Green);

            var accountName = "";
            var password1   = "";
            var password2   = "";

            do
            {
                accountName = nameLine.GetInputString(false);
                password1   = pass1Line.GetInputString(true);
                password2   = pass2Line.GetInputString(true);

                LineTools.ClearAt(nameCoord, accountName);
                LineTools.ClearAt(pass1Coord, password1);
                LineTools.ClearAt(pass2Coord, password2);
            } while (password1 != password2 || accountName.Length <= 5 || password1.Length <= 5);

            _namepass = (accountName, password1);
            if (DatabaseManagement.AccountManagement.Exists(accountName, true))
            {
                ConsoleWriter.ClearScreen();
                LineTools.SetCursor(nameCoord);
                Console.Write("Account name is already taken!");
                Console.ReadLine();
                return(Option.Start);
            }

            return(Option.RegisterShip);
        }
Example #5
0
        public PointF GetIntersectionTest(
            PointF lineFirstStar,
            PointF lineFirstEnd,
            PointF lineSecondStar,
            PointF lineSecondEnd
            )
        {
            PointF result = LineTools.GetIntersection
                                (lineFirstStar, lineFirstEnd, lineSecondStar, lineSecondEnd);

            return(result);
            // TODO: 将断言添加到 方法 LineToolsTest.GetIntersectionTest(PointF, PointF, PointF, PointF)
        }
Example #6
0
        bool DistanceToHullAcceptable(Vertices polygon, Vector2 point, bool higherDetail)
        {
            if (polygon == null)
            {
                throw new ArgumentNullException(nameof(polygon), "'polygon' can't be null.");
            }

            if (polygon.Count < 3)
            {
                throw new ArgumentException("'polygon.Count' can't be less then 3.");
            }


            Vector2 edgeVertex2 = polygon[polygon.Count - 1];
            Vector2 edgeVertex1;

            if (higherDetail)
            {
                for (int i = 0; i < polygon.Count; i++)
                {
                    edgeVertex1 = polygon[i];

                    if (LineTools.DistanceBetweenPointAndLineSegment(ref point, ref edgeVertex1, ref edgeVertex2) <=
                        _hullTolerance || Vector2.Distance(point, edgeVertex1) <= _hullTolerance)
                    {
                        return(false);
                    }

                    edgeVertex2 = polygon[i];
                }

                return(true);
            }
            else
            {
                for (int i = 0; i < polygon.Count; i++)
                {
                    edgeVertex1 = polygon[i];

                    if (LineTools.DistanceBetweenPointAndLineSegment(ref point, ref edgeVertex1, ref edgeVertex2) <=
                        _hullTolerance)
                    {
                        return(false);
                    }

                    edgeVertex2 = polygon[i];
                }

                return(true);
            }
        }
 private static bool CanSee(int i, int j, Vertices vertices)
 {
     if (Reflex(i, vertices))
     {
         if (LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)) &&
             RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)))
         {
             return(false);
         }
     }
     else
     {
         if (RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)) ||
             LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)))
         {
             return(false);
         }
     }
     if (Reflex(j, vertices))
     {
         if (LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)) &&
             RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)))
         {
             return(false);
         }
     }
     else
     {
         if (RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)) ||
             LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)))
         {
             return(false);
         }
     }
     for (int k = 0; k < vertices.Count; ++k)
     {
         if ((k + 1) % vertices.Count == i || k == i || (k + 1) % vertices.Count == j || k == j)
         {
             continue; // ignore incident edges
         }
         //if(QLineF(at(i), at(j)).intersect(QLineF(at(k), at(k + 1)), NULL) == QLineF::BoundedIntersection) {
         if (LineTools.LineIntersect(At(i, vertices), At(j, vertices), At(k, vertices), At(k + 1, vertices)) !=
             Vector2.Zero)
         {
             return(false);
         }
     }
     return(true);
 }
Example #8
0
        private static void SimplifySection(Vertices vertices, int i, int j, bool[] usePoint, float distanceTolerance)
        {
            if ((i + 1) == j)
            {
                return;
            }

            Vector2 a = vertices[i];
            Vector2 b = vertices[j];

            double maxDistance = -1.0;
            int    maxIndex    = i;

            for (int k = i + 1; k < j; k++)
            {
                Vector2 point = vertices[k];

                double distance = LineTools.DistanceBetweenPointAndLineSegment(ref point, ref a, ref b);

                if (distance > maxDistance)
                {
                    maxDistance = distance;
                    maxIndex    = k;
                }
            }

            if (maxDistance <= distanceTolerance)
            {
                for (int k = i + 1; k < j; k++)
                {
                    usePoint[k] = false;
                }
            }
            else
            {
                SimplifySection(vertices, i, maxIndex, usePoint, distanceTolerance);
                SimplifySection(vertices, maxIndex, j, usePoint, distanceTolerance);
            }
        }
Example #9
0
        public static Option Account()
        {
            ConsoleWriter.ClearScreen();
            var lines     = File.ReadAllLines(@"UI/maps/6.Account.txt");
            var drawables = TextEditor.Add.DrawablesAt(lines, 0);

            TextEditor.Center.ToScreen(drawables, Console.WindowWidth, Console.WindowHeight);
            var parameterCoords = drawables.FindAll(x => x.Chars == "¤").ToList()
                                  .Select(x => (x.CoordinateX, x.CoordinateY)).ToList();

            var nameCoord = parameterCoords[0];
            var shipCoord = parameterCoords[1];

            var selectionList = new SelectionList <Option>(ForegroundColor, '$');

            selectionList.GetCharPositions(drawables);
            selectionList.AddSelections(new[]
            {
                Option.Parking,
                Option.Receipts,
                Option.ReRegisterShip,
                Option.Homeplanet,
                Option.Logout,
                Option.Exit
            });
            ConsoleWriter.TryAppend(drawables);
            ConsoleWriter.Update();

            Console.ForegroundColor = ConsoleColor.Green;
            LineTools.SetCursor(nameCoord);
            Console.Write(_account.User.Name);
            LineTools.SetCursor(shipCoord);
            Console.Write(_account.SpaceShip.Model);

            return(selectionList.GetSelection());
        }
Example #10
0
        /// <summary>
        /// Calculates all intersections between two polygons.
        /// </summary>
        /// <param name="polygon1">The first polygon.</param>
        /// <param name="polygon2">The second polygon.</param>
        /// <param name="slicedPoly1">Returns the first polygon with added intersection points.</param>
        /// <param name="slicedPoly2">Returns the second polygon with added intersection points.</param>
        private static void CalculateIntersections(Vertices polygon1, Vertices polygon2,
                                                   out Vertices slicedPoly1, out Vertices slicedPoly2)
        {
            slicedPoly1 = new Vertices(polygon1);
            slicedPoly2 = new Vertices(polygon2);

            // Iterate through polygon1's edges
            for (int i = 0; i < polygon1.Count; i++)
            {
                // Get edge vertices
                Vector2 a = polygon1[i];
                Vector2 b = polygon1[polygon1.NextIndex(i)];

                // Get intersections between this edge and polygon2
                for (int j = 0; j < polygon2.Count; j++)
                {
                    Vector2 c = polygon2[j];
                    Vector2 d = polygon2[polygon2.NextIndex(j)];

                    Vector2 intersectionPoint;
                    // Check if the edges intersect
                    if (LineTools.LineIntersect(a, b, c, d, out intersectionPoint))
                    {
                        // calculate alpha values for sorting multiple intersections points on a edge
                        float alpha;
                        // Insert intersection point into first polygon
                        alpha = GetAlpha(a, b, intersectionPoint);
                        if (alpha > 0f && alpha < 1f)
                        {
                            int index = slicedPoly1.IndexOf(a) + 1;
                            while (index < slicedPoly1.Count &&
                                   GetAlpha(a, b, slicedPoly1[index]) <= alpha)
                            {
                                ++index;
                            }
                            slicedPoly1.Insert(index, intersectionPoint);
                        }
                        // Insert intersection point into second polygon
                        alpha = GetAlpha(c, d, intersectionPoint);
                        if (alpha > 0f && alpha < 1f)
                        {
                            int index = slicedPoly2.IndexOf(c) + 1;
                            while (index < slicedPoly2.Count &&
                                   GetAlpha(c, d, slicedPoly2[index]) <= alpha)
                            {
                                ++index;
                            }
                            slicedPoly2.Insert(index, intersectionPoint);
                        }
                    }
                }
            }
            // Check for very small edges
            for (int i = 0; i < slicedPoly1.Count; ++i)
            {
                int iNext = slicedPoly1.NextIndex(i);
                //If they are closer than the distance remove vertex
                if ((slicedPoly1[iNext] - slicedPoly1[i]).sqrMagnitude <= ClipperEpsilonSquared)
                {
                    slicedPoly1.RemoveAt(i);
                    --i;
                }
            }
            for (int i = 0; i < slicedPoly2.Count; ++i)
            {
                int iNext = slicedPoly2.NextIndex(i);
                //If they are closer than the distance remove vertex
                if ((slicedPoly2[iNext] - slicedPoly2[i]).sqrMagnitude <= ClipperEpsilonSquared)
                {
                    slicedPoly2.RemoveAt(i);
                    --i;
                }
            }
        }
Example #11
0
        private static List <Vertices> TriangulatePolygon(Vertices vertices)
        {
            List <Vertices> list = new List <Vertices>();
            Vector2         lowerInt = new Vector2();
            Vector2         upperInt = new Vector2(); // intersection points
            int             lowerIndex = 0, upperIndex = 0;
            Vertices        lowerPoly, upperPoly;

            for (int i = 0; i < vertices.Count; ++i)
            {
                if (Reflex(i, vertices))
                {
                    float upperDist;
                    float lowerDist = upperDist = float.MaxValue;
                    for (int j = 0; j < vertices.Count; ++j)
                    {
                        // if line intersects with an edge
                        float   d;
                        Vector2 p;
                        if (Left(At(i - 1, vertices), At(i, vertices), At(j, vertices)) && RightOn(At(i - 1, vertices), At(i, vertices), At(j - 1, vertices)))
                        {
                            // find the point of intersection
                            p = LineTools.LineIntersect(At(i - 1, vertices), At(i, vertices), At(j, vertices), At(j - 1, vertices));

                            if (Right(At(i + 1, vertices), At(i, vertices), p))
                            {
                                // make sure it's inside the poly
                                d = SquareDist(At(i, vertices), p);
                                if (d < lowerDist)
                                {
                                    // keep only the closest intersection
                                    lowerDist  = d;
                                    lowerInt   = p;
                                    lowerIndex = j;
                                }
                            }
                        }

                        if (Left(At(i + 1, vertices), At(i, vertices), At(j + 1, vertices)) && RightOn(At(i + 1, vertices), At(i, vertices), At(j, vertices)))
                        {
                            p = LineTools.LineIntersect(At(i + 1, vertices), At(i, vertices), At(j, vertices), At(j + 1, vertices));

                            if (Left(At(i - 1, vertices), At(i, vertices), p))
                            {
                                d = SquareDist(At(i, vertices), p);
                                if (d < upperDist)
                                {
                                    upperDist  = d;
                                    upperIndex = j;
                                    upperInt   = p;
                                }
                            }
                        }
                    }

                    // if there are no vertices to connect to, choose a point in the middle
                    if (lowerIndex == (upperIndex + 1) % vertices.Count)
                    {
                        Vector2 p = ((lowerInt + upperInt) / 2);

                        lowerPoly = Copy(i, upperIndex, vertices);
                        lowerPoly.Add(p);
                        upperPoly = Copy(lowerIndex, i, vertices);
                        upperPoly.Add(p);
                    }
                    else
                    {
                        double highestScore = 0, bestIndex = lowerIndex;
                        while (upperIndex < lowerIndex)
                        {
                            upperIndex += vertices.Count;
                        }

                        for (int j = lowerIndex; j <= upperIndex; ++j)
                        {
                            if (CanSee(i, j, vertices))
                            {
                                double score = 1 / (SquareDist(At(i, vertices), At(j, vertices)) + 1);
                                if (Reflex(j, vertices))
                                {
                                    if (RightOn(At(j - 1, vertices), At(j, vertices), At(i, vertices)) && LeftOn(At(j + 1, vertices), At(j, vertices), At(i, vertices)))
                                    {
                                        score += 3;
                                    }
                                    else
                                    {
                                        score += 2;
                                    }
                                }
                                else
                                {
                                    score += 1;
                                }
                                if (score > highestScore)
                                {
                                    bestIndex    = j;
                                    highestScore = score;
                                }
                            }
                        }
                        lowerPoly = Copy(i, (int)bestIndex, vertices);
                        upperPoly = Copy((int)bestIndex, i, vertices);
                    }
                    list.AddRange(TriangulatePolygon(lowerPoly));
                    list.AddRange(TriangulatePolygon(upperPoly));
                    return(list);
                }
            }

            // polygon is already convex
            if (vertices.Count > Settings.MaxPolygonVertices)
            {
                lowerPoly = Copy(0, vertices.Count / 2, vertices);
                upperPoly = Copy(vertices.Count / 2, 0, vertices);
                list.AddRange(TriangulatePolygon(lowerPoly));
                list.AddRange(TriangulatePolygon(upperPoly));
            }
            else
            {
                list.Add(vertices);
            }

            return(list);
        }
Example #12
0
        public static Option Identification()
        {
            ConsoleWriter.ClearScreen();
            var lines     = File.ReadAllLines(@"UI/maps/3a.Identification.txt");
            var drawables = TextEditor.Add.DrawablesAt(lines, 0);

            TextEditor.Center.ToScreen(drawables, Console.WindowWidth, Console.WindowHeight);
            ConsoleWriter.TryAppend(drawables);
            ConsoleWriter.Update();
            Console.CursorVisible   = true;
            Console.ForegroundColor = ConsoleColor.Green;

            Func <string, (int X, int Y)> GetCoord = chr =>
            {
                var drawable = drawables.Find(x => x.Chars == chr);
                return(drawable.CoordinateX, drawable.CoordinateY);
            };
            Action <string> Clear = clear =>
            {
                Console.CursorVisible = false;
                foreach (var c in clear)
                {
                    Console.Write(" ");
                }
                Console.CursorVisible = true;
            };

            var fCoord       = GetCoord("F");
            var nameEndCoord = GetCoord(":");

            LineTools.SetCursor((nameEndCoord.X + 2, nameEndCoord.Y));
            var username = Console.ReadLine();

            LineTools.ClearAt(fCoord, "First name: " + username);
            Console.Write("Security question loading...");

            Func <string, string> getSecurityAnswer = securityQuestion =>
            {
                LineTools.ClearAt(fCoord, "Security question loading...");
                Console.Write(securityQuestion + " ");
                return(Console.ReadLine());
            };

            var user = DatabaseManagement.AccountManagement.IdentifyWithQuestion(username, getSecurityAnswer);

            LineTools.ClearAt(fCoord, "Security question loading... plus the long answer that i cleared now!");

            if (user == null)
            {
                ConsoleWriter.ClearScreen();
                LineTools.SetCursor(fCoord);
                Console.Write("Incorrect answer or incorrect name input");
                Console.ReadKey(true);
                return(Option.Start);
            }

            var registrationExists = DatabaseManagement.AccountManagement.Exists(username, true);
            var userExists         = DatabaseManagement.AccountManagement.Exists(user.Name, false);

            if (registrationExists == false && userExists == false)
            {
                _account.User = user;
                return(Option.Registration);
            }


            LineTools.SetCursor(fCoord);
            Console.WriteLine("User is already registered");
            Thread.Sleep(1000);
            return(Option.Start);
        }
        /// <summary>
        /// Precondition: Counter Clockwise polygon
        /// Decompose the polygon into several smaller non-concave polygon.
        /// If the polygon is already convex, it will return the original polygon, unless it is over Settings.MaxPolygonVertices.
        /// </summary>
        /// <param name="vertices"></param>
        /// <returns></returns>
        public static List <Vertices> ConvexPartition(Vertices vertices)
        {
            List <Vertices> list = new List <Vertices>();
            float           d, dist1, dist2;
            Vector2         ip;
            Vector2         ip1 = new Vector2();
            Vector2         ip2 = new Vector2(); // intersection points
            int             ind1 = 0, ind2 = 0;
            Vertices        poly1, poly2;

            for (int i = 0; i < vertices.Count; ++i)
            {
                if (Reflex(i, vertices))
                {
                    dist1 = dist2 = float.MaxValue; // std::numeric_limits<qreal>::max();
                    for (int j = 0; j < vertices.Count; ++j)
                    {
                        if (Left(At(i - 1, vertices), At(i, vertices), At(j, vertices)) &&
                            RightOn(At(i - 1, vertices), At(i, vertices), At(j - 1, vertices)))
                        {
                            // if ray (i-1)->(i) intersects with edge (j, j-1)
                            //QLineF(at(i - 1), at(i)).intersect(QLineF(at(j), at(j - 1)), ip);
                            ip = LineTools.LineIntersect(At(i - 1, vertices), At(i, vertices), At(j, vertices),
                                                         At(j - 1, vertices));
                            if (Right(At(i + 1, vertices), At(i, vertices), ip))
                            {
                                // intersection point isn't caused by backwards ray
                                d = SquareDist(At(i, vertices), ip);
                                if (d < dist1)
                                {
                                    // take the closest intersection so we know it isn't blocked by another edge
                                    dist1 = d;
                                    ind1  = j;
                                    ip1   = ip;
                                }
                            }
                        }
                        if (Left(At(i + 1, vertices), At(i, vertices), At(j + 1, vertices)) &&
                            RightOn(At(i + 1, vertices), At(i, vertices), At(j, vertices)))
                        {
                            // if ray (i+1)->(i) intersects with edge (j+1, j)
                            //QLineF(at(i + 1), at(i)).intersect(QLineF(at(j), at(j + 1)), ip);
                            ip = LineTools.LineIntersect(At(i + 1, vertices), At(i, vertices), At(j, vertices),
                                                         At(j + 1, vertices));
                            if (Left(At(i - 1, vertices), At(i, vertices), ip))
                            {
                                d = SquareDist(At(i, vertices), ip);
                                if (d < dist2)
                                {
                                    dist2 = d;
                                    ind2  = j;
                                    ip2   = ip;
                                }
                            }
                        }
                    }
                    if (ind1 == (ind2 + 1) % vertices.Count)
                    {
                        // no vertices in range
                        Vector2 sp = ((ip1 + ip2) / 2);
                        poly1 = Copy(i, ind2, vertices);
                        poly1.Add(sp);
                        poly2 = Copy(ind1, i, vertices);
                        poly2.Add(sp);
                    }
                    else
                    {
                        double highestScore = 0, bestIndex = ind1;
                        while (ind2 < ind1)
                        {
                            ind2 += vertices.Count;
                        }
                        for (int j = ind1; j <= ind2; ++j)
                        {
                            if (CanSee(i, j, vertices))
                            {
                                double score = 1 / (SquareDist(At(i, vertices), At(j, vertices)) + 1);
                                if (Reflex(j, vertices))
                                {
                                    if (RightOn(At(j - 1, vertices), At(j, vertices), At(i, vertices)) &&
                                        LeftOn(At(j + 1, vertices), At(j, vertices), At(i, vertices)))
                                    {
                                        score += 3;
                                    }
                                    else
                                    {
                                        score += 2;
                                    }
                                }
                                else
                                {
                                    score += 1;
                                }
                                if (score > highestScore)
                                {
                                    bestIndex    = j;
                                    highestScore = score;
                                }
                            }
                        }
                        poly1 = Copy(i, (int)bestIndex, vertices);
                        poly2 = Copy((int)bestIndex, i, vertices);
                    }
                    list.AddRange(ConvexPartition(poly1));
                    list.AddRange(ConvexPartition(poly2));
                    return(list);
                }
            }

            // polygon is already convex
            if (vertices.Count > Settings.MaxPolygonVertices)
            {
                poly1 = Copy(0, vertices.Count / 2, vertices);
                poly2 = Copy(vertices.Count / 2, 0, vertices);
                list.AddRange(ConvexPartition(poly1));
                list.AddRange(ConvexPartition(poly2));
            }
            else
            {
                list.Add(vertices);
            }

            //The polygons are not guaranteed to be without collinear points. We remove
            //them to be sure.
            for (int i = 0; i < list.Count; i++)
            {
                list[i] = SimplifyTools.CollinearSimplify(list[i], 0);
            }

            return(list);
        }
Example #14
0
        //TODO: Reenable the rounding if it is necessary for the boolean tools to work.
        /// <summary>
        /// Rounds vertices X and Y values to whole numbers.
        /// </summary>
        /// <param name="polygon">The polygon whose vertices should be rounded.</param>
        /// <returns>A new polygon with rounded vertices.</returns>
        //public static Vertices Round(Vertices polygon)
        //{
        //    Vertices returnPoly = new Vertices();
        //    for (int i = 0; i < polygon.Count; i++)
        //        returnPoly.Add(new Vector2((float)Math.Round(polygon[i].X, 0), (float)Math.Round(polygon[i].Y, 0)));

        //    return returnPoly;
        //}

        /// <summary>
        /// Determines if three vertices are collinear (ie. on a straight line)
        /// </summary>
        /// <param name="p1">Vertex 1</param>
        /// <param name="p2">Vertex 2</param>
        /// <param name="p3">Vertex 3</param>
        /// <returns></returns>
        public static bool VerticesAreCollinear(ref Vector2 p1, ref Vector2 p2, ref Vector2 p3)
        {
            float collinearity = (p3.X - p1.X) * (p2.Y - p1.Y) + (p3.Y - p1.Y) * (p1.X - p2.X);

            return(LineTools.FloatEquals(collinearity, 0, 0.00001f));
        }
Example #15
0
        private bool SplitPolygonEdge(Vertices polygon, Vector2 coordInsideThePolygon, out int vertex1Index, out int vertex2Index)
        {
            Vector2 slope;
            int     nearestEdgeVertex1Index = 0;
            int     nearestEdgeVertex2Index = 0;
            bool    edgeFound = false;

            float shortestDistance = float.MaxValue;

            bool    edgeCoordFound = false;
            Vector2 foundEdgeCoord = Vector2.Zero;

            List <float> xCoords = SearchCrossingEdges(polygon, (int)coordInsideThePolygon.Y);

            vertex1Index = 0;
            vertex2Index = 0;

            foundEdgeCoord.Y = coordInsideThePolygon.Y;

            if (xCoords != null && xCoords.Count > 1 && xCoords.Count % 2 == 0)
            {
                float distance;
                for (int i = 0; i < xCoords.Count; i++)
                {
                    if (xCoords[i] < coordInsideThePolygon.X)
                    {
                        distance = coordInsideThePolygon.X - xCoords[i];

                        if (distance < shortestDistance)
                        {
                            shortestDistance = distance;
                            foundEdgeCoord.X = xCoords[i];

                            edgeCoordFound = true;
                        }
                    }
                }

                if (edgeCoordFound)
                {
                    shortestDistance = float.MaxValue;

                    int edgeVertex2Index = polygon.Count - 1;

                    int edgeVertex1Index;
                    for (edgeVertex1Index = 0; edgeVertex1Index < polygon.Count; edgeVertex1Index++)
                    {
                        Vector2 tempVector1 = polygon[edgeVertex1Index];
                        Vector2 tempVector2 = polygon[edgeVertex2Index];
                        distance = LineTools.DistanceBetweenPointAndLineSegment(ref foundEdgeCoord,
                                                                                ref tempVector1, ref tempVector2);
                        if (distance < shortestDistance)
                        {
                            shortestDistance = distance;

                            nearestEdgeVertex1Index = edgeVertex1Index;
                            nearestEdgeVertex2Index = edgeVertex2Index;

                            edgeFound = true;
                        }

                        edgeVertex2Index = edgeVertex1Index;
                    }

                    if (edgeFound)
                    {
                        slope = polygon[nearestEdgeVertex2Index] - polygon[nearestEdgeVertex1Index];
                        slope.Normalize();

                        Vector2 tempVector = polygon[nearestEdgeVertex1Index];
                        distance = Vector2.Distance(tempVector, foundEdgeCoord);

                        vertex1Index = nearestEdgeVertex1Index;
                        vertex2Index = nearestEdgeVertex1Index + 1;

                        polygon.Insert(nearestEdgeVertex1Index, distance * slope + polygon[vertex1Index]);
                        polygon.Insert(nearestEdgeVertex1Index, distance * slope + polygon[vertex2Index]);

                        return(true);
                    }
                }
            }

            return(false);
        }
Example #16
0
        /// <summary>
        /// Decompose the polygon into several smaller non-concave polygon.
        /// If the polygon is already convex, it will return the original polygon, unless it is over Settings.MaxPolygonVertices.
        /// Precondition: Counter Clockwise polygon
        /// </summary>
        /// <param name="vertices"></param>
        /// <returns></returns>
        public static List <Vertices> ConvexPartition(Vertices vertices)
        {
            //We force it to CCW as it is a precondition in this algorithm.
            vertices.ForceCounterClockWise();

            List <Vertices> list = new List <Vertices>();
            float           d, lowerDist, upperDist;
            Vector2         p;
            Vector2         lowerInt = new Vector2();
            Vector2         upperInt = new Vector2(); // intersection points
            int             lowerIndex = 0, upperIndex = 0;
            Vertices        lowerPoly, upperPoly;

            for (int i = 0; i < vertices.Count; ++i)
            {
                if (Reflex(i, vertices))
                {
                    lowerDist = upperDist = float.MaxValue; // std::numeric_limits<qreal>::max();
                    for (int j = 0; j < vertices.Count; ++j)
                    {
                        // if line intersects with an edge
                        if (Left(At(i - 1, vertices), At(i, vertices), At(j, vertices)) &&
                            RightOn(At(i - 1, vertices), At(i, vertices), At(j - 1, vertices)))
                        {
                            // find the point of intersection
                            p = LineTools.LineIntersect(At(i - 1, vertices), At(i, vertices), At(j, vertices),
                                                        At(j - 1, vertices));
                            if (Right(At(i + 1, vertices), At(i, vertices), p))
                            {
                                // make sure it's inside the poly
                                d = SquareDist(At(i, vertices), p);
                                if (d < lowerDist)
                                {
                                    // keep only the closest intersection
                                    lowerDist  = d;
                                    lowerInt   = p;
                                    lowerIndex = j;
                                }
                            }
                        }

                        if (Left(At(i + 1, vertices), At(i, vertices), At(j + 1, vertices)) &&
                            RightOn(At(i + 1, vertices), At(i, vertices), At(j, vertices)))
                        {
                            p = LineTools.LineIntersect(At(i + 1, vertices), At(i, vertices), At(j, vertices),
                                                        At(j + 1, vertices));
                            if (Left(At(i - 1, vertices), At(i, vertices), p))
                            {
                                d = SquareDist(At(i, vertices), p);
                                if (d < upperDist)
                                {
                                    upperDist  = d;
                                    upperIndex = j;
                                    upperInt   = p;
                                }
                            }
                        }
                    }

                    // if there are no vertices to connect to, choose a point in the middle
                    if (lowerIndex == (upperIndex + 1) % vertices.Count)
                    {
                        Vector2 sp = ((lowerInt + upperInt) / 2);

                        lowerPoly = Copy(i, upperIndex, vertices);
                        lowerPoly.Add(sp);
                        upperPoly = Copy(lowerIndex, i, vertices);
                        upperPoly.Add(sp);
                    }
                    else
                    {
                        double highestScore = 0, bestIndex = lowerIndex;
                        while (upperIndex < lowerIndex)
                        {
                            upperIndex += vertices.Count;
                        }
                        for (int j = lowerIndex; j <= upperIndex; ++j)
                        {
                            if (CanSee(i, j, vertices))
                            {
                                double score = 1 / (SquareDist(At(i, vertices), At(j, vertices)) + 1);
                                if (Reflex(j, vertices))
                                {
                                    if (RightOn(At(j - 1, vertices), At(j, vertices), At(i, vertices)) &&
                                        LeftOn(At(j + 1, vertices), At(j, vertices), At(i, vertices)))
                                    {
                                        score += 3;
                                    }
                                    else
                                    {
                                        score += 2;
                                    }
                                }
                                else
                                {
                                    score += 1;
                                }
                                if (score > highestScore)
                                {
                                    bestIndex    = j;
                                    highestScore = score;
                                }
                            }
                        }
                        lowerPoly = Copy(i, (int)bestIndex, vertices);
                        upperPoly = Copy((int)bestIndex, i, vertices);
                    }
                    list.AddRange(ConvexPartition(lowerPoly));
                    list.AddRange(ConvexPartition(upperPoly));
                    return(list);
                }
            }

            // polygon is already convex
            if (vertices.Count > Settings.MaxPolygonVertices)
            {
                lowerPoly = Copy(0, vertices.Count / 2, vertices);
                upperPoly = Copy(vertices.Count / 2, 0, vertices);
                list.AddRange(ConvexPartition(lowerPoly));
                list.AddRange(ConvexPartition(upperPoly));
            }
            else
            {
                list.Add(vertices);
            }

            //The polygons are not guaranteed to be without collinear points. We remove
            //them to be sure.
            for (int i = 0; i < list.Count; i++)
            {
                list[i] = SimplifyTools.CollinearSimplify(list[i], 0);
            }

            //Remove empty vertice collections
            for (int i = list.Count - 1; i >= 0; i--)
            {
                if (list[i].Count == 0)
                {
                    list.RemoveAt(i);
                }
            }

            return(list);
        }
Example #17
0
        public static Option Parking()
        {
            ConsoleWriter.ClearScreen();

            var lines     = File.ReadAllLines(@"UI/maps/7.Parking.txt");
            var drawables = TextEditor.Add.DrawablesAt(lines, 0);

            TextEditor.Center.ToScreen(drawables, Console.WindowWidth, Console.WindowHeight);
            var selectionList = new SelectionList <Option>(ConsoleColor.Green, '$');

            selectionList.GetCharPositions(drawables);
            selectionList.AddSelections(new[]
            {
                Option.PurchaseTicket,
                Option.ReEnterhours,
                Option.Account
            });

            var drawProps      = drawables.FindAll(x => x.Chars == "¤");
            var props          = drawProps.Select(x => (x.CoordinateX, x.CoordinateY)).ToList();
            var parkFromXY     = props[0];
            var pricePerHourXY = props[1];
            var shipLengthXY   = props[2];

            var calculatedPriceXY = props[3];
            var enterHoursXY      = props[4];
            var receiptXY         = props[5];
            var openNext          = DatabaseManagement.ParkingManagement.CheckParkingStatus();

            Console.ForegroundColor = ConsoleColor.Green;
            LineTools.SetCursor(parkFromXY);

            if (openNext.isOpen)
            {
                Console.Write("Now");
            }
            else
            {
                Console.Write(openNext.nextAvailable);
            }

            LineTools.SetCursor(pricePerHourXY);
            Console.Write(DatabaseManagement.ParkingManagement.CalculatePrice(_account.SpaceShip, 1) * 60);
            LineTools.SetCursor(shipLengthXY);
            Console.Write(_account.SpaceShip.ShipLength);

            ConsoleWriter.TryAppend(drawables.Except(drawProps).ToList());
            ConsoleWriter.Update();

            Option menuSel;
            double hours;


            var timeGetter = new TimeGetter(enterHoursXY, calculatedPriceXY, 10000,
                                            DatabaseManagement.ParkingManagement.CalculatePrice);

            if (openNext.isOpen == false)
            {
                Console.ReadKey(true);
                return(Option.Account);
            }

            do
            {
                hours   = timeGetter.GetMinutes(_account.SpaceShip);
                menuSel = selectionList.GetSelection();

                if (menuSel == Option.PurchaseTicket && hours == 0)
                {
                    menuSel = Option.ReEnterhours;
                }
            } while (menuSel == Option.ReEnterhours);

            if (Option.PurchaseTicket == menuSel)
            {
                ConsoleWriter.ClearScreen();

                var receipt = DatabaseManagement.ParkingManagement.SendInvoice(_account, hours);
                var boxData = new BoxData((Console.WindowWidth / 2 - 10, parkFromXY.CoordinateY));
                boxData.Update(new[] { "Loading receipt..." });

                string[] receiptString =
                {
                    "Purchase successful!",
                    "",
                    "Ticket Holder: " + receipt.Account.AccountName,
                    "Start time: " + receipt.StartTime,
                    "End time: " + receipt.EndTime,
                    "Price: " + receipt.Price
                };
                boxData.Update(receiptString);

                Console.ReadKey(true);
            }

            return(Option.Account);
        }