Ejemplo n.º 1
0
        public bool TwoSegmentsIntersectionTest(Line L1, Line L2)
        {
            Enums.TurnType first_orientation  = HelperMethods.CheckTurn(L1, L2.Start);
            Enums.TurnType second_orientation = HelperMethods.CheckTurn(L1, L2.End);
            Enums.TurnType third_orientation  = HelperMethods.CheckTurn(L2, L1.Start);
            Enums.TurnType fourth_orientation = HelperMethods.CheckTurn(L2, L1.End);

            if (first_orientation != second_orientation && third_orientation != fourth_orientation)
            {
                return(true);
            }
            if (first_orientation == Enums.TurnType.Colinear && HelperMethods.PointOnSegment(L2.Start, L1.Start, L1.End))
            {
                return(true);
            }
            if (second_orientation == Enums.TurnType.Colinear && HelperMethods.PointOnSegment(L2.End, L1.Start, L1.End))
            {
                return(true);
            }
            if (third_orientation == Enums.TurnType.Colinear && HelperMethods.PointOnSegment(L1.Start, L2.Start, L2.End))
            {
                return(true);
            }
            if (fourth_orientation == Enums.TurnType.Colinear && HelperMethods.PointOnSegment(L1.End, L2.Start, L2.End))
            {
                return(true);
            }

            return(false);
        }
        public bool polygonInCCW(List <Point> polygon)
        {
            // 1. Get Point with Min X
            double extMin        = 1e9;
            int    minPointIndex = -1;

            for (int i = 0; i < polygon.Count; ++i)
            {
                if ((polygon[i].X < extMin) || (polygon[i].X == extMin && polygon[i].Y < polygon[minPointIndex].Y))
                {
                    extMin        = polygon[i].X;
                    minPointIndex = i;
                }
            }
            int prev, next;

            prev = HelperMethods.getPrevIndex(minPointIndex, polygon.Count);
            next = HelperMethods.getNextIndex(minPointIndex, polygon.Count);
            Line line = new Line(polygon[prev], polygon[next]);

            Enums.TurnType type = HelperMethods.CheckTurn(line, polygon[minPointIndex]);
            if (type == Enums.TurnType.Left)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
        public bool polygonCCW(List <Point> myPolygon)
        {
            double mini          = 1e9;
            int    minPointIndex = -1;

            for (int i = 0; i < myPolygon.Count; i++)
            {
                if (myPolygon[i].X < mini || myPolygon[i].X == mini && myPolygon[i].Y < myPolygon[minPointIndex].Y)
                {
                    mini          = myPolygon[i].X;
                    minPointIndex = i;
                }
            }
            int prev, next;

            prev = HelperMethods.getPrevIndex(minPointIndex, myPolygon.Count);
            next = HelperMethods.getNextIndex(minPointIndex, myPolygon.Count);
            Line line = new Line(myPolygon[prev], myPolygon[next]);

            Enums.TurnType type = HelperMethods.CheckTurn(line, myPolygon[minPointIndex]);
            if (type == Enums.TurnType.Left)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            if (points.Count == 0 || polygons.Count == 0)
            {
                return;
            }

            int idx = 0;

            Enums.TurnType prevSide = Enums.TurnType.Left;//dummy value
            bool           inside   = true;

            foreach (Point p in points)
            {
                idx    = 0;
                inside = true;
                foreach (Line l in polygons[0].lines)
                {
                    var curSide = HelperMethods.CheckTurn(l, p);
                    if (idx != 0)
                    {
                        if (curSide != prevSide)
                        {
                            inside = false;
                        }
                    }
                    prevSide = curSide;
                    idx++;
                }
                if (inside)
                {
                    outPoints.Add(p);
                }
            }
        }
        public override void Run(
            List <Point> points, List <Line> lines, List <Polygon> polygons,
            ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygon)
        {
            bool x = false, y = false;

            Enums.TurnType e1 = HelperMethods.CheckTurn(lines[0], lines[1].Start);
            Enums.TurnType e2 = HelperMethods.CheckTurn(lines[0], lines[1].End);
            if ((e1 == Enums.TurnType.Left && e2 == Enums.TurnType.Left) || (e1 == Enums.TurnType.Right && e2 == Enums.TurnType.Right))
            {
                x = true;
            }

            e1 = HelperMethods.CheckTurn(lines[1], lines[0].Start);
            e2 = HelperMethods.CheckTurn(lines[1], lines[0].End);
            if ((e1 == Enums.TurnType.Left && e2 == Enums.TurnType.Left) || (e1 == Enums.TurnType.Right && e2 == Enums.TurnType.Right))
            {
                y = true;
            }

            if (!x && !y)
            {
                outLines.Add(lines[0]);
            }
        }
Ejemplo n.º 6
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            /*
             *  [on purpose]
             *  don't handle repeated points
             *  neither colinear points
             */

            if (polygons[0].lines.Count != 3)
            {// not a triangle
                return;
            }
            Line  l1 = polygons[0].lines[0];
            Line  l2 = polygons[0].lines[1];
            Line  l3 = polygons[0].lines[2];
            Point p  = points[0];

            Enums.TurnType t1 = HelperMethods.CheckTurn(l1, p);
            Enums.TurnType t2 = HelperMethods.CheckTurn(l2, p);
            Enums.TurnType t3 = HelperMethods.CheckTurn(l3, p);
            // have to be inside the triangle not colinear with one of the edges
            // not repeated points
            if (t1 == t2 && t2 == t3)
            {
                outPoints.Add(p);
            }
            return;
        }
Ejemplo n.º 7
0
        public Participant AddParticipant(Guid gameId, Guid categoryId, Enums.TurnType turnType, string userId)
        {
            try
            {
                var duplicateParticipants = _context.Participants.Where(x => x.GameId == gameId && x.UserId == userId && x.Deleted == null);
                if (duplicateParticipants.Any())
                {
                    throw new DataException("User is already participating in this game.");
                }

                var participant = new Participant()
                {
                    UserId   = userId,
                    GameId   = gameId,
                    TurnType = turnType
                };

                var addedparticipant = _context.Add(participant).Entity;

                var gameCategory = new GameCategory()
                {
                    CategoryId    = categoryId,
                    GameId        = gameId,
                    ParticipantId = addedparticipant.Id
                };
                _context.Add(gameCategory);

                _context.SaveChanges();
                return(addedparticipant);
            }
            catch (Exception e)
            {
                throw new DataException("Could not add new participant", e);
            }
        }
Ejemplo n.º 8
0
        public override void Run(
            List <Point> points, List <Line> lines, List <Polygon> polygons,
            ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygon)
        {
            int left = 0, right = 0;

            for (int i = 0; i < polygons[0].lines.Count; i++)
            {
                Enums.TurnType e = HelperMethods.CheckTurn(polygons[0].lines[i], points[0]);
                if (e == Enums.TurnType.Left)
                {
                    left++;
                }
                else if (e == Enums.TurnType.Right)
                {
                    right++;
                }
            }
            if (left == 3 || right == 3)
            {
                outLines.Add(polygons[0].lines[0]);
                outLines.Add(polygons[0].lines[1]);
                outLines.Add(polygons[0].lines[2]);
            }
            else
            {
                outPoints.Add(points[0]);
            }
        }
Ejemplo n.º 9
0
        public void OnPress(object sender, EventArgs e)
        {
            var pressedButton = sender as Button;

            Enums.TurnType turnType = default;

            currentPlayer = currentPlayer == 1 ? 2 : 1;

            switch (currentPlayer)
            {
            case 1:
                turnType = Enums.TurnType.Cross;
                pressedButton.BackgroundImage = crossImage;
                pressedButton.Enabled         = false;
                break;

            case 2:
                turnType = Enums.TurnType.Zero;
                pressedButton.BackgroundImage = zeroImage;
                pressedButton.Enabled         = false;
                break;
            }
            if (_buttonsMap.TryGetValue(pressedButton.Name, out var turnPoint))
            {
                _gameController.MakeTurn(turnPoint, turnType);
            }
            if (_gameController.CheckState())
            {
                MessageBox.Show("Game ended. New game started a few moment later!");
                RenderTableWithButtons();
            }
        }
        public bool LinesIntersect(Line l1, Line l2)
        {
            bool x = false, y = false;

            Enums.TurnType e1 = HelperMethods.CheckTurn(l1, l2.Start);
            Enums.TurnType e2 = HelperMethods.CheckTurn(l1, l2.End);
            if ((e1 == Enums.TurnType.Left && e2 == Enums.TurnType.Left) || (e1 == Enums.TurnType.Right && e2 == Enums.TurnType.Right))
            {
                x = true;
            }

            e1 = HelperMethods.CheckTurn(l2, l1.Start);
            e2 = HelperMethods.CheckTurn(l2, l1.End);
            if ((e1 == Enums.TurnType.Left && e2 == Enums.TurnType.Left) || (e1 == Enums.TurnType.Right && e2 == Enums.TurnType.Right))
            {
                y = true;
            }

            if (x || y)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Ejemplo n.º 11
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            if (points.Count <= 3)
            {
                outPoints = points;
                return;
            }

            //get extreames(minX, maxX)
            Point  minXP = new Point(0, 0), maxXP = new Point(0, 0);
            double minx = 100000000;
            double maxx = -100000000;

            for (int i = 0; i < points.Count; i++)
            {
                if (points[i].X < minx)
                {
                    minx  = points[i].X;
                    minXP = points[i];
                }
                if (points[i].X > maxx)
                {
                    maxx  = points[i].X;
                    maxXP = points[i];
                }
            }
            //add two points to quickhull
            CH.Add(minXP);
            CH.Add(maxXP);

            //make a line btw them
            Line lineL = new Line(minXP, maxXP);
            Line lineR = new Line(maxXP, minXP);

            //split data
            List <Point> left  = new List <Point>();
            List <Point> right = new List <Point>();

            for (int i = 0; i < points.Count; i++)
            {
                Enums.TurnType turnType = HelperMethods.CheckTurn(lineL, points[i]);
                if (turnType == Enums.TurnType.Left)
                {
                    left.Add(points[i]);
                }
                else if (turnType == Enums.TurnType.Right)
                {
                    right.Add(points[i]);
                }
            }


            Quickhull(left, lineL);
            Quickhull(right, lineR);

            outPoints = CH;
        }
Ejemplo n.º 12
0
        public void Quickhull(List <Point> points, Line line)
        {
            //for each point get h
            //then get max h
            //cross(a,b) = 1/4 b*h
            //get h
            if (points.Count <= 0)
            {
                return;
            }

            double maxh = 0;
            Point  maxP = new Point(0, 0);

            for (int i = 0; i < points.Count; i++)
            {
                double h = getH(line, points[i]);
                if (Math.Abs(h) > maxh)
                {
                    maxh = h;
                    maxP = points[i];
                }
            }
            //add the point to convex hull
            CH.Add(maxP);

            List <Point> leftPoints  = new List <Point>();
            List <Point> rightPoints = new List <Point>();


            Line leftLine  = new Line(line.Start, maxP);
            Line rightLine = new Line(maxP, line.End);

            for (int i = 0; i < points.Count; i++)
            {
                Enums.TurnType       turnType       = HelperMethods.CheckTurn(leftLine, points[i]);
                Enums.PointInPolygon pointInPolygon = HelperMethods.PointInTriangle(points[i], maxP, line.Start, line.End);

                if (turnType == Enums.TurnType.Left)
                {
                    leftPoints.Add(points[i]);
                }
                else if (pointInPolygon == Enums.PointInPolygon.Outside)
                {
                    rightPoints.Add(points[i]);
                }

                // turnType = HelperMethods.CheckTurn(rightLine, points[i]);
                // if (turnType == Enums.TurnType.Right) rightPoints.Add(points[i]);
            }


            Quickhull(leftPoints, leftLine);
            Quickhull(rightPoints, rightLine);
        }
Ejemplo n.º 13
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            /*
             *   how to handle buggy cases with H and V lines !??
             */
            Line l1 = lines[0];
            Line l2 = lines[1];

            if (parallel_line(l1, l2))
            {
                return;
            }

            double s1 = (l1.Start.Y - l1.End.Y) / (l1.Start.X - l1.End.X);
            double s2 = (l2.Start.Y - l2.End.Y) / (l2.Start.X - l2.End.X);

            double b1 = l1.Start.Y - s1 * l1.Start.X;
            double b2 = l2.Start.Y - s2 * l2.Start.X;

            // point of intersection (treating segments as lines)
            double y = (s2 * b1 - s1 * b2) / (s2 - s1);

            double x = 0;

            if (s1 != 0)
            {
                x = (y - b1) / s1;  //  BUG it divides by zero and the test cases have Horizontal line and this give x =nan as inter point which
            }
            // can't be drawn on the canves
            else
            {
                x = (y - b2) / s2;
            }

            // check if the point is inside th segments

            /*
             * // naive logic
             * if(x >= Math.Min(l1.Start.X , l1.End.X) && x <= Math.Max(l1.Start.X, l1.End.X))
             *  if (y >= Math.Min(l1.Start.Y, l1.End.Y) && y <= Math.Max(l1.Start.Y, l1.End.Y))
             *      if (x >= Math.Min(l2.Start.X, l2.End.X) && x <= Math.Max(l2.Start.X, l2.End.X))
             *          if (y >= Math.Min(l2.Start.Y, l2.End.Y) && y <= Math.Max(l2.Start.Y, l2.End.Y))
             *              outPoints.Add(new Point(x, y));
             */

            // using orientation test
            Enums.TurnType t1 = HelperMethods.CheckTurn(l1, l2.Start);
            Enums.TurnType t2 = HelperMethods.CheckTurn(l1, l2.End);
            Enums.TurnType t3 = HelperMethods.CheckTurn(l2, l1.Start);
            Enums.TurnType t4 = HelperMethods.CheckTurn(l2, l1.End);
            if (t1 != t2 && t3 != t4)
            {
                outPoints.Add(new Point(x, y));
            }
        }
Ejemplo n.º 14
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            HashSet <PointComparer> hashP = new HashSet <PointComparer>();

            for (int i = 0; i < points.Count; ++i)
            {
                hashP.Add(new PointComparer(points[i]));
            }
            PointComparer[] res = hashP.ToArray();
            points.Clear();
            for (int i = 0; i < res.Length; ++i)
            {
                points.Add(res[i].p);
            }
            if (points.Count < 4)
            {
                outPoints = new List <Point>(points);
                return;
            }
            HashSet <Point> setPoints = new HashSet <Point>();

            for (int i = 0; i < points.Count; ++i)
            {
                for (int j = i + 1; j < points.Count; ++j)
                {
                    Enums.TurnType turn = HelperMethods.CheckTurn(new Line(points[i], points[j]), points[0]);
                    bool           ok   = true;
                    for (int k = 0; k < points.Count; ++k)
                    {
                        if (valid(i, j, k))
                        {
                            Enums.TurnType curTurn = HelperMethods.CheckTurn(new Line(points[i], points[j]), points[k]);
                            turn = (turn == Enums.TurnType.Colinear) ? curTurn : turn;
                            if (curTurn != Enums.TurnType.Colinear && turn != curTurn)
                            {
                                ok = false; break;
                            }
                            else if (curTurn == Enums.TurnType.Colinear && !HelperMethods.PointOnLine(points[k], points[i], points[j]))
                            {
                                ok = false; break;
                            }
                        }
                    }

                    if (ok)
                    {
                        setPoints.Add(points[i]); setPoints.Add(points[j]);
                    }
                }
            }
            outPoints = new List <Point>(setPoints);
        }
Ejemplo n.º 15
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            if (polygons[0].lines.Count < 3 || points.Count == 0)
            { // not valid case to be solved
                return;
            }
            // line to right of given point
            Point       a             = points[0];
            Point       b             = new Point(a.X + 10000, a.Y);
            Line        vir_line      = new Line(a, b);
            List <Line> poly_segments = polygons[0].lines;

            // this may be bad practice
            segment_segment_intersection seg_inter = new segment_segment_intersection();

            // do segment - segment intersection for vir_line with all the segments of the concave polygon
            for (int i = 0; i < poly_segments.Count; i++)
            {
                Line poly_seg = poly_segments[i];
                // check segment - segment intersection
                List <Line> tmp_lines = new List <Line>();
                tmp_lines.Add(vir_line);
                tmp_lines.Add(poly_seg);

                /*
                 * this will add points of intersections to outpoints list
                 * so we have to delete them later
                 */
                seg_inter.Run(points, tmp_lines, polygons, ref outPoints, ref outLines, ref outPolygons);

                // check for colinearity (point is on a polygon segment)
                Enums.TurnType t = HelperMethods.CheckTurn(poly_seg, a);
                if (t == Enums.TurnType.Colinear && check_point_inside_segment(poly_seg, a))
                {
                    outPoints.Clear(); // clear points of intersections
                    outPoints.Add(a);
                    return;
                }
            }

            // intersect odd number of segments = inside the polygon
            if (outPoints.Count % 2 != 0)
            {
                outPoints.Clear(); // clear points of intersections
                outPoints.Add(a);
            }
            else
            {
                outPoints.Clear();
            }
            return;
        }
Ejemplo n.º 16
0
        public vertexType getVertexType(int index) //index of vertex
        {
            Enums.TurnType turn = new Enums.TurnType();
            //double angle = 0;

            Point Prev, Vertex, Next;

            Vertex = P.lines[index].Start;
            Next   = P.lines[index % P.lines.Count].End;
            if (index == 0)
            {
                Prev = P.lines[P.lines.Count - 1].Start;
            }
            else
            {
                Prev = P.lines[index - 1].Start;
            }

            turn = HelperMethods.CheckTurn(new Line(Prev, Vertex), Next);

            /*
             * Point CB = new Point(Vertex.X - Prev.X, Vertex.Y - Prev.Y);
             * Point BA = new Point(Next.X - Vertex.X , Next.Y - Vertex.Y);
             * double dot = (CB.X * BA.Y) - (CB.Y * BA.X);
             * double CBnorm = Math.Sqrt((CB.X * CB.X) + (CB.Y * CB.Y));
             * double BAnorm = Math.Sqrt((BA.X * BA.X) + (BA.Y * BA.Y));
             *
             * angle = Math.Abs(Math.Asin(dot / (CBnorm * BAnorm)));*/

            //Left <180, Right >180
            if (turn == Enums.TurnType.Left && Prev.Y < Vertex.Y && Next.Y < Vertex.Y)
            {
                return(vertexType.Start);
            }
            else if (turn == Enums.TurnType.Right && Prev.Y < Vertex.Y && Next.Y < Vertex.Y)
            {
                return(vertexType.Split);
            }
            else if (turn == Enums.TurnType.Left && Prev.Y > Vertex.Y && Next.Y > Vertex.Y)
            {
                return(vertexType.End);
            }
            else if (turn == Enums.TurnType.Right && Prev.Y > Vertex.Y && Next.Y > Vertex.Y)
            {
                return(vertexType.Merge);
            }
            else
            {
                return(vertexType.Regular);
            }
        }
Ejemplo n.º 17
0
 public override void Run(
     List <Point> points, List <Line> lines, List <Polygon> polygons,
     ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygon)
 {
     Enums.TurnType e = HelperMethods.CheckTurn(lines[0], points[0]);
     if (e == Enums.TurnType.Left)
     {
         outPoints.Add(points[0]);
     }
     else
     {
         outLines.Add(lines[0]);
     }
 }
        public bool isConvex(int pointIndex, List <Point> myPolygon)
        {
            int prev, next;

            prev = HelperMethods.getPrevIndex(pointIndex, myPolygon.Count);
            next = HelperMethods.getNextIndex(pointIndex, myPolygon.Count);
            Line line = new Line(myPolygon[prev], myPolygon[pointIndex]);

            Enums.TurnType type = HelperMethods.CheckTurn(line, myPolygon[next]);
            if (type == Enums.TurnType.Left)
            {
                return(true);
            }
            return(false);
        }
Ejemplo n.º 19
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            /*
             * this function assume that the line is at index 0
             * and the segment is at index 1
             */
            Line l   = lines[0];
            Line seg = lines[1];

            if (parallel_line(l, seg))
            {
                return;
            }

            // get point of intersection as if they are lines
            double s1 = (l.Start.Y - l.End.Y) / (l.Start.X - l.End.X);
            double s2 = (seg.Start.Y - seg.End.Y) / (seg.Start.X - seg.End.X);

            double b1 = l.Start.Y - s1 * l.Start.X;
            double b2 = seg.Start.Y - s2 * seg.Start.X;

            // point of intersection (treating segments as lines)
            double y = (s2 * b1 - s1 * b2) / (s2 - s1);
            double x = (y - b1) / s1;

            // check the intersection
            Enums.TurnType t1 = HelperMethods.CheckTurn(l, seg.Start);
            Enums.TurnType t2 = HelperMethods.CheckTurn(l, seg.End);
            if (t1 != t2)
            {
                Enums.TurnType t3 = HelperMethods.CheckTurn(seg, l.Start);
                Enums.TurnType t4 = HelperMethods.CheckTurn(seg, l.End);
                if (t1 == Enums.TurnType.Left && t3 == Enums.TurnType.Right)
                {
                    outPoints.Add(new Point(x, y));
                }
                else if (t1 == Enums.TurnType.Right && t3 == Enums.TurnType.Left)
                {
                    outPoints.Add(new Point(x, y));
                }
                // coolinear end points case
                else if (t3 == Enums.TurnType.Colinear || t4 == Enums.TurnType.Colinear)
                {
                    outPoints.Add(new Point(x, y));
                }
            }
        }
Ejemplo n.º 20
0
        private void lastCase(List <Point> p)
        {
            Point p1 = p[0], p2 = p[1], np = p.Last();

            Enums.TurnType turn = HelperMethods.CheckTurn(new Line(p2, p1), np);
            if (turn == Enums.TurnType.Right)
            {
                p.RemoveAt(0);
            }
            else if (turn == Enums.TurnType.Colinear)
            {
                if (HelperMethods.distance(p2, p1) < HelperMethods.distance(p2, np))
                {
                    p.RemoveAt(0);
                }
            }
        }
Ejemplo n.º 21
0
        public int Compare(Point b, Point c)
        {
            /*
             *  function return :
             *  0 if b == c
             *  1 if b > c
             *  -1 if  b < c
             *  in angular manner
             *
             *  logic :
             * check turn
             * if from a to b to c is turn right so c have less angler value than b return c less then b
             * else if right left turn si b<c
             * else if colinear check for furthest one , return any threr will be no problem
             */

            Line seg = new Line(a, b);

            Enums.TurnType t = HelperMethods.CheckTurn(seg, c);
            if (t == Enums.TurnType.Right)
            {
                return(1);
            }
            else if (t == Enums.TurnType.Left)
            {
                return(-1);
            }

            else
            {// colinear
                double bdis = get_dis2(a, b);
                double cdis = get_dis2(a, c);
                if (bdis >= cdis)
                {
                    return(1);
                }
                else
                {
                    return(-1);
                }
            }
        }
        public static bool IsSupportLine(Line l, List <Point> points)
        {
            int idx = 0;

            Enums.TurnType prevSide = Enums.TurnType.Left;//dummy value
            bool           inside   = true;

            foreach (Point p in points)
            {
                if (p.Equals(l.Start) || p.Equals(l.End))
                {
                    continue;
                }

                var curSide = HelperMethods.CheckTurn(l, p);

                if (curSide == Enums.TurnType.Colinear)
                {
                    var dst1 = Point.GetSqrDistance(l.Start, l.End);
                    var dst2 = Point.GetSqrDistance(l.Start, p);
                    if (dst1 < dst2)
                    {
                        inside = false;
                        break;
                    }
                }
                if (idx != 0)
                {
                    if (curSide != prevSide)
                    {
                        inside = false;
                        break;
                    }
                }
                prevSide = curSide;
                idx++;
            }
            return(inside);
        }
        public bool isConvex(LinkedListNode <Point> pointIndex, LinkedList <Point> _polygon)
        {
            LinkedListNode <Point> prev = pointIndex.Previous;
            LinkedListNode <Point> next = pointIndex.Next;

            if (prev == null)
            {
                prev = _polygon.Last;
            }
            if (next == null)
            {
                next = _polygon.First;
            }
            Line line = new Line(prev.Value, pointIndex.Value);

            Enums.TurnType type = HelperMethods.CheckTurn(line, next.Value);
            if (type == Enums.TurnType.Left)
            {
                return(true);
            }
            return(false);
        }
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            if (lines.Count == 0 || polygons.Count == 0)
            {
                return;
            }
            int idx = 0;

            Enums.TurnType prevSide = Enums.TurnType.Left;//dummy value
            bool           check;

            foreach (Line l in lines)
            {
                check = true;
                foreach (Line pl in polygons[0].lines)
                {
                    var t1 = HelperMethods.CheckTurn(l, pl.Start);
                    var t2 = HelperMethods.CheckTurn(l, pl.End);
                    if (t1 != t2)
                    {
                        check = false;
                    }
                    if (idx != 0)
                    {
                        if (prevSide != t1)
                        {
                            check = false;
                        }
                    }
                    prevSide = t1;
                    idx++;
                }
                if (check)
                {
                    outLines.Add(l);
                }
            }
        }
Ejemplo n.º 25
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            /*
             *  this function require lines to have start and end poitns
             *  in a s pecific order CCW or CW
             *  line order it self don't mater
             */

            // as point inside concave polygon is a general algo for
            // any kind of polygon we can just call the other function here

            List <Line> l = polygons[0].lines;
            Point       p = points[0];

            int left = 0, right = 0;

            for (int i = 0; i < l.Count; i++)
            {
                Line tmp_l = l[i];
                // check turn
                Enums.TurnType t = HelperMethods.CheckTurn(tmp_l, p);
                if (t == Enums.TurnType.Left)
                {
                    left += 1;
                }
                else if (t == Enums.TurnType.Right)
                {
                    right += 1;
                }
                // else colinear , no problem
            }
            if (left == 0 || right == 0)
            {
                outPoints.Add(p);
            }
            return;
        }
Ejemplo n.º 26
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            // handle non logical cases
            if (points.Count == 0)
            {
                return;
            }

            /*
             * input : set of points
             * return : segments , points in CCW manner
             * check how the algo will behave for many colinear points  !!!!!!
             */

            int          minp_index   = get_min_point_index(points);
            Point        minp         = points[minp_index];
            my_sort_algo anguler_sort = new my_sort_algo(minp);

            /*
             * sort the points in angular manner respect to min point
             * sort using turn left and turn right
             */

            List <Point> sorted_points = points;

            sorted_points.Sort(anguler_sort);

            // apply graham scan algo
            List <Point> hull = new List <Point>();

            // ***********************

            /*
             * this introduce a bug , why !???
             * if(minp!=sorted_points[0])
             * {
             *  return;
             * }*/
            // ***********************

            hull.Add(minp);
            if (points.Count == 1)
            {
                outPoints.Add(minp);
                return;
            }

            hull.Add(sorted_points[1]);
            for (int i = 2; i < sorted_points.Count; i++)
            {
                int   index = hull.Count - 1;
                Point a     = hull[index - 1];
                Point b     = hull[index];
                Point c     = sorted_points[i];

                // check turn
                Line           seg = new Line(a, b);
                Enums.TurnType t   = HelperMethods.CheckTurn(seg, c);
                if (t == Enums.TurnType.Left)
                {
                    hull.Add(c);
                }
                else if (t == Enums.TurnType.Right)
                {
                    // c enclose some points that are on the boundary of the hull

                    hull.RemoveAt(hull.Count - 1);  // O(1)
                    i -= 1;

                    // don't go further untill we are making left turn
                    // as hull could have more points that are enclosed by c
                }
                else // colinear , pick farthest
                {
                    // only 2 points could be colinear with c
                    // I don't think that we need to get the dis
                    // c is farther than b

                    double bdis = get_dis2(a, b);
                    double cdis = get_dis2(a, c);
                    if (cdis > bdis)
                    {
                        hull.RemoveAt(hull.Count - 1); // O(1) no further elements to shift left
                        hull.Add(c);
                    }
                }
            }


            /*
             * handle similar points
             */
            if (hull.Count == 2)
            {
                if (Math.Abs(hull[0].X - hull[1].X) <= Constants.Epsilon && Math.Abs(hull[0].Y - hull[1].Y) <= Constants.Epsilon)
                {
                    hull.RemoveAt(hull.Count - 1);
                }
            }

            // return
            for (int i = 0; i < hull.Count; i++)
            {
                if (i > 0)
                {
                    outLines.Add(new Line(hull[i - 1], hull[i]));
                }
                outPoints.Add(hull[i]);
            }
            if (hull.Count > 2) // closing segment
            {
                outLines.Add(new Line(hull[hull.Count - 1], hull[0]));
            }
            return;
        }
        void merger(List<Point> conv1, List<Point> conv2, out int[] L, out int[] R)
        {
            int conv1Idx = 0, conv2Idx = 0;
            for (int i = 0; i < conv1.Count; ++i)
                if (conv1[i].X > conv1[conv1Idx].X)
                    conv1Idx = i;
            for (int i = 0; i < conv2.Count; ++i)
                if (conv2[i].X < conv2[conv2Idx].X)
                    conv2Idx = i;
            L = new int[2]; R = new int[2];
            L[0] = L[1] = conv1Idx;
            R[0] = R[1] = conv2Idx;

            int[] op = new int[2] { 1, -1 }; Enums.TurnType[] type = new Enums.TurnType[2] { Enums.TurnType.Right, Enums.TurnType.Left };
            for (int state = 0; state < 2; ++state)
            {
                bool doneR = true, doneL = true;
                do
                {
                    doneR = true; doneL = true;
                    while (true)
                    {
                        int rNxt = (R[1 - state] + op[state] + conv2.Count) % conv2.Count;
                        Enums.TurnType  turn = HelperMethods.CheckTurn(new Line(conv2[rNxt], conv2[R[1 - state]]), conv1[L[1 - state]]);
                        if (turn == type[1 - state] || turn == Enums.TurnType.Colinear)
                        { R[1 - state] = rNxt; doneR = false; }
                        else
                            break;
                    }
                    while (true)
                    {
                        int lPrev = (L[1 - state] + op[1 - state] + conv1.Count) % conv1.Count;
                        Enums.TurnType turn = HelperMethods.CheckTurn(new Line(conv1[lPrev], conv1[L[1 - state]]), conv2[R[1 - state]]);
                        if (turn == type[state] || turn == Enums.TurnType.Colinear)
                        { L[1 - state] = lPrev; doneL = false; }
                        else
                            break;
                    }
                } while (!doneR || !doneL) ;
            }
        }
Ejemplo n.º 28
0
        public override void Run(System.Collections.Generic.List <CGUtilities.Point> points, System.Collections.Generic.List <CGUtilities.Line> lines, System.Collections.Generic.List <CGUtilities.Polygon> polygons, ref System.Collections.Generic.List <CGUtilities.Point> outPoints, ref System.Collections.Generic.List <CGUtilities.Line> outLines, ref System.Collections.Generic.List <CGUtilities.Polygon> outPolygons)
        {
            // Step [ 1 ] :: first at all we must check that polygon points is Sorted CCW
            // Step [ 1 ] :: first at all we must check that polygon points is Sorted CCW


            List <Point> input = new List <Point>(); //

            // get minimum_X to use it in checking that the polygon points are sorted CCW OR Not
            for (int i = 0; i < polygons[0].lines.Count(); i++)
            {
                Point p = polygons[0].lines[i].Start;
                if (p.X <= mini_x.X)
                {
                    if (p.X < mini_x.X)
                    {
                        mini_x          = p;
                        index_of_mini_x = i;
                    }

                    else if (p.Y < mini_x.Y)
                    {
                        mini_x          = p;
                        index_of_mini_x = i;
                    }
                }
                input.Add(p);
            }

            bool Points_sorted_CCW = HelperMethods.IS_points_Sorted_CCW(mini_x, index_of_mini_x, input);

            // if points were sorted CC then Resort them to be CCW
            if (Points_sorted_CCW == false)
            {
                /* for (int i = 0; i < polygons[0].lines.Count; i++)
                 * {
                 *   Point temp = polygons[0].lines[i].Start;
                 *
                 *   polygons[0].lines[i].Start = polygons[0].lines[i].End;
                 *   polygons[0].lines[i].End = temp;
                 *
                 * }*/
                polygons[0].lines.Reverse();
                input.Reverse();
            } // Now we have ploygon sorted CCW



            // Step [ 2 ] :: Check that the polygon is Monotone
            // Step [ 2 ] :: Check that the polygon is Monotone
            bool is_Montone = Check_Poly_IS_Monotone(input);

            if (is_Montone)
            {
                List <Smart_point_Y_monotone>  Sorted_Points = Sort_Polygon(input);
                Stack <Smart_point_Y_monotone> My_Stack      = new Stack <Smart_point_Y_monotone>();
                My_Stack.Push(Sorted_Points[0]);
                My_Stack.Push(Sorted_Points[1]);

                int ind = 2;
                while (ind != Sorted_Points.Count())
                {
                    Smart_point_Y_monotone V         = Sorted_Points[ind];
                    Smart_point_Y_monotone First_Top = My_Stack.Peek();
                    if (V.chain.Equals(First_Top.chain)) // Same Chain
                    {
                        My_Stack.Pop();
                        Smart_point_Y_monotone Sceond_Top = My_Stack.Peek();

                        if (First_Top.chain == "left")
                        {
                            Line           line       = new Line(Sceond_Top.current_point, First_Top.current_point);
                            Enums.TurnType chain_Type = HelperMethods.CheckTurn(line, V.current_point);
                            if (chain_Type == Enums.TurnType.Left)
                            {
                                outLines.Add(new Line(V.current_point, Sceond_Top.current_point));
                                if (My_Stack.Count == 1)
                                {
                                    My_Stack.Push(V);
                                    ind++;
                                }
                            }
                            else
                            {
                                My_Stack.Push(First_Top);
                                My_Stack.Push(V);
                                ind++;
                            }
                        } // end of condition Same Chain && chain is Left


                        else if (First_Top.chain == "right")
                        {
                            Line           line = new Line(Sceond_Top.current_point, First_Top.current_point);
                            Enums.TurnType type = HelperMethods.CheckTurn(line, V.current_point);
                            if (type == Enums.TurnType.Right)
                            {
                                outLines.Add(new Line(V.current_point, Sceond_Top.current_point));
                                if (My_Stack.Count == 1)
                                {
                                    My_Stack.Push(V);
                                    ind++;
                                }
                            }
                            else
                            {
                                My_Stack.Push(First_Top);
                                My_Stack.Push(V);
                                ind++;
                            }
                        } //end of condtion Same Cahin && chain is Right
                    }     //end of Same Chain

                    else  // oppsite Chain
                    {
                        while (My_Stack.Count != 1)
                        {
                            Smart_point_Y_monotone sceond_Top = My_Stack.Pop();
                            outLines.Add(new Line(V.current_point, sceond_Top.current_point));
                        }
                        My_Stack.Pop();
                        My_Stack.Push(First_Top);
                        My_Stack.Push(V);
                        ind++;
                    } //end of Oppsite Chain
                }     //end of big while loop
            }         //end of condition poly is monotone
            outLines.Remove(outLines[outLines.Count - 1]);
        }             //end of Run
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            if (points.Count == 1)
            {
                outPoints.Add(points[0]);
            }
            else
            {
                double minY  = 100000;
                double minX  = -1000;
                int    index = -1;
                //bageeb el min y with max x
                for (int i = 0; i < points.Count; i++)
                {
                    if ((points[i].Y < minY) || (points[i].Y == minY && points[i].X >= minX))
                    {
                        index = i;
                        minY  = points[i].Y;
                        minX  = points[i].X;
                    }
                }

                Point  minPoint     = points[index];
                double x            = minPoint.X + 100000000;
                double y            = minPoint.Y;
                Point  virtualPoint = new Point(x, y);
                points.RemoveAt(index);
                List <KeyValuePair <double, Point> > sortedAngles = new List <KeyValuePair <double, Point> >();
                for (int i = 0; i < points.Count; i++)
                {
                    double angle = CalcAngle(minPoint, virtualPoint, points[i]);

                    sortedAngles.Add(new KeyValuePair <double, Point>(angle, points[i]));
                }

                sortedAngles.Sort((s, ss) => s.Key.CompareTo(ss.Key));
                Stack <Point> myStack = new Stack <Point>();
                myStack.Push(minPoint);
                myStack.Push(sortedAngles[0].Value);

                for (int i = 1; i < points.Count; i++)
                {
                    Point p1 = myStack.Pop();
                    Point p2 = myStack.Pop();
                    myStack.Push(p2);
                    myStack.Push(p1);
                    Line           l = new Line(p1, p2);
                    Enums.TurnType t = HelperMethods.CheckTurn(l, sortedAngles[i].Value);

                    while (myStack.Count > 2 && t != Enums.TurnType.Left)
                    {
                        myStack.Pop();

                        p1 = myStack.Pop();
                        p2 = myStack.Pop();

                        myStack.Push(p2);
                        myStack.Push(p1);
                        l = new Line(p1, p2);
                        t = HelperMethods.CheckTurn(l, sortedAngles[i].Value);
                    }

                    myStack.Push(sortedAngles[i].Value);
                }


                while (myStack.Count != 0)
                {
                    outPoints.Add(myStack.Pop());
                }
            }

            // special cases
            /////////////////////////////
            List <Point> temp = new List <Point>();

            temp.Clear();
            for (int i = 0; i < outPoints.Count; ++i)
            {
                temp.Add(outPoints[i]);
            }
            outPoints.Clear();
            for (int i = 0; i < temp.Count; ++i)
            {
                List <Point> diagonal = new List <Point>();
                diagonal.Add(temp[i]);
                for (int j = 0; j < temp.Count; ++j)
                {
                    if ((i != j) && (temp[i].X - temp[j].X == temp[i].Y - temp[j].Y))
                    {
                        diagonal.Add(temp[j]);
                    }
                }
                // keda ma3aya kol el no2at el 3ala nfs el 5at
                // 3amalna sort bel x wel y
                diagonal = diagonal.OrderBy(x => x.X).ThenBy(x => x.Y).ToList();
                // 3ashan lw el point mtkarara maslan 3ala kaza diagonal
                if (!outPoints.Contains(diagonal[0]))
                {
                    outPoints.Add(diagonal[0]);
                }
                // lazem nt2aked size el diagonal akbar men 1 3ashan mn3melsh access le 7aga out of range
                if (diagonal.Count > 1 && !outPoints.Contains(diagonal[diagonal.Count - 1]))
                {
                    outPoints.Add(diagonal[diagonal.Count - 1]);
                }
            }
            ///////////////////////////////

            temp.Clear();
            for (int i = 0; i < outPoints.Count; ++i)
            {
                temp.Add(outPoints[i]);
            }
            outPoints.Clear();
            for (int i = 0; i < temp.Count; ++i)
            {
                List <Point> verticalLine = new List <Point>();
                verticalLine.Add(temp[i]);
                for (int j = 0; j < temp.Count; ++j)
                {
                    if (i != j && temp[i].X == temp[j].X)
                    {
                        verticalLine.Add(temp[j]);
                    }
                }

                verticalLine = verticalLine.OrderBy(x => x.Y).ToList();
                if (!outPoints.Contains(verticalLine[0]))
                {
                    outPoints.Add(verticalLine[0]);
                }
                if (verticalLine.Count > 1 && !outPoints.Contains(verticalLine[verticalLine.Count - 1]))
                {
                    outPoints.Add(verticalLine[verticalLine.Count - 1]);
                }
            }

            ////////////////////////////////////////////////////////////
            temp.Clear();

            for (int i = 0; i < outPoints.Count; ++i)
            {
                temp.Add(outPoints[i]);
            }
            outPoints.Clear();
            for (int i = 0; i < temp.Count; ++i)
            {
                List <Point> horizontalLine = new List <Point>();
                horizontalLine.Add(temp[i]);
                for (int j = 0; j < temp.Count; ++j)
                {
                    if (i != j && temp[i].Y == temp[j].Y)
                    {
                        horizontalLine.Add(temp[j]);
                    }
                }

                horizontalLine = horizontalLine.OrderBy(x => x.X).ToList();
                if (!outPoints.Contains(horizontalLine[0]))
                {
                    outPoints.Add(horizontalLine[0]);
                }
                if (horizontalLine.Count > 1 && !outPoints.Contains(horizontalLine[horizontalLine.Count - 1]))
                {
                    outPoints.Add(horizontalLine[horizontalLine.Count - 1]);
                }
            }
        }
Ejemplo n.º 30
0
        public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            /*
             * this function will take set of points
             * return only the points on the boundary of the polygon
             * it don't deal with colinear points
             * we could make the algo faster by excluding the non extreme points from building the triangle also
             * proof that this will not affect the non extreme detection !!! ******
             */

            /*
             * this will affect outpoints and I will deal with it to make things alright
             */

            // preprocessing
            List <Point> tmp = new List <Point>();

            for (int i = 0; i < points.Count; i++)
            {
                bool dup = false;
                for (int j = 0; j < i; j++)
                {
                    if (Math.Abs(points[i].X - points[j].X) <= Constants.Epsilon && Math.Abs(points[i].Y - points[j].Y) <= Constants.Epsilon)
                    {
                        dup = true;
                        break;
                    }
                }
                if (dup)
                {
                    continue;
                }
                tmp.Add(points[i]);
            }
            points.Clear();
            points = tmp;

            Point_in_convex_polygon check_p_in_t = new Point_in_convex_polygon();

            bool[] is_extreme = new bool[points.Count];
            for (int i = 0; i < points.Count; i++)
            {
                is_extreme[i] = true;
            }

            for (int i = 0; i < points.Count; i++)
            {
                // don't use non extreme points in checking
                // as if we have the same point more than 1 time they will exclude each other
                if (is_extreme[i] == false)
                {
                    continue;
                }

                for (int j = 0; j < points.Count; j++)
                {
                    if (is_extreme[j] == false)
                    {
                        continue;
                    }
                    if (i == j)
                    {
                        continue;
                    }

                    for (int k = 0; k < points.Count; k++)
                    {
                        if (is_extreme[k] == false)
                        {
                            continue;
                        }
                        if (k == i || k == j)
                        {
                            continue;
                        }
                        Point a = points[i], b = points[j], c = points[k];

                        // check if points are colinear
                        Enums.TurnType t = HelperMethods.CheckTurn(new Line(a, b), c);
                        if (t == Enums.TurnType.Colinear)
                        {
                            continue;
                        }

                        // loop throw the points
                        for (int index = 0; index < points.Count; index++)
                        {
                            if (is_extreme[index] == false || index == i || index == j || index == k)
                            {
                                continue;
                            }
                            // check if the point is inside the polygon triangle
                            List <Line>    tmp_ll   = new List <Line>();
                            List <Polygon> tmp_pl   = new List <Polygon>();
                            Polygon        tmp_poly = new Polygon();
                            Point          p        = points[index];

                            // does the order matters !???
                            tmp_ll.Add(new Line(a, b));
                            tmp_ll.Add(new Line(b, c));
                            tmp_ll.Add(new Line(c, a));

                            tmp_poly.lines = tmp_ll;
                            tmp_pl.Add(tmp_poly);

                            // tmp out lists
                            // does C# have garbage collector !??
                            List <Point>   tmp_outpoints   = new List <Point>();
                            List <Line>    tmp_outlines    = new List <Line>();
                            List <Polygon> tmp_outpolygons = new List <Polygon>();
                            List <Point>   in_points       = new List <Point>();
                            in_points.Add(p);
                            check_p_in_t.Run(in_points, new List <Line>(), tmp_pl, ref tmp_outpoints, ref tmp_outlines, ref tmp_outpolygons);
                            if (tmp_outpoints.Count != 0)
                            {
                                is_extreme[index] = false;
                            }
                        }
                    }
                }
            }

            // return extreme points
            for (int i = 0; i < points.Count; i++)
            {
                if (is_extreme[i] == true)
                {
                    outPoints.Add(points[i]);
                }
            }
            return;
        }
Ejemplo n.º 31
0
        void merger(List <Point> conv1, List <Point> conv2, out int[] L, out int[] R)
        {
            int conv1Idx = 0, conv2Idx = 0;

            for (int i = 0; i < conv1.Count; ++i)
            {
                if (conv1[i].X > conv1[conv1Idx].X)
                {
                    conv1Idx = i;
                }
            }
            for (int i = 0; i < conv2.Count; ++i)
            {
                if (conv2[i].X < conv2[conv2Idx].X)
                {
                    conv2Idx = i;
                }
            }
            L    = new int[2]; R = new int[2];
            L[0] = L[1] = conv1Idx;
            R[0] = R[1] = conv2Idx;

            int[] op = new int[2] {
                1, -1
            }; Enums.TurnType[] type = new Enums.TurnType[2] {
                Enums.TurnType.Right, Enums.TurnType.Left
            };
            for (int state = 0; state < 2; ++state)
            {
                bool doneR = true, doneL = true;
                do
                {
                    doneR = true; doneL = true;
                    while (true)
                    {
                        int            rNxt = (R[1 - state] + op[state] + conv2.Count) % conv2.Count;
                        Enums.TurnType turn = HelperMethods.CheckTurn(new Line(conv2[rNxt], conv2[R[1 - state]]), conv1[L[1 - state]]);
                        if (turn == type[1 - state] || turn == Enums.TurnType.Colinear)
                        {
                            R[1 - state] = rNxt; doneR = false;
                        }
                        else
                        {
                            break;
                        }
                    }
                    while (true)
                    {
                        int            lPrev = (L[1 - state] + op[1 - state] + conv1.Count) % conv1.Count;
                        Enums.TurnType turn  = HelperMethods.CheckTurn(new Line(conv1[lPrev], conv1[L[1 - state]]), conv2[R[1 - state]]);
                        if (turn == type[state] || turn == Enums.TurnType.Colinear)
                        {
                            L[1 - state] = lPrev; doneL = false;
                        }
                        else
                        {
                            break;
                        }
                    }
                } while (!doneR || !doneL);
            }
        }