Exemple #1
0
        public bool Encloses(List <Point> points)
        {
            List <Line> helpers = new List <Line>();

            foreach (Point point in points)
            {
                helpers.Add(new Line(point, new Point(DRAWING_SCREEN_WIDTH, point.Y)));
            }

            foreach (Line helper in helpers)
            {
                //foreach (Side side1 in Sides)
                //{
                //    side1.Checked = false;
                //}

                List <Side> VisualSides = GetVisualSides();

                int intersectCount = 0;

                bool isPointPartOfTheEdge = VisualSides.Any(s => s.IsPartOfMe(helper.Start));

                if (!isPointPartOfTheEdge)
                {
                    foreach (Side side in VisualSides)
                    {
                        if (side.Checked == false)
                        {
                            Orientation first  = GetOrientation(helper.Start, helper.End, side.Start);
                            Orientation second = GetOrientation(helper.Start, helper.End, side.End);
                            Orientation third  = GetOrientation(side.Start, side.End, helper.Start);
                            Orientation fourth = GetOrientation(side.Start, side.End, helper.End);

                            List <Orientation> orientations = new List <Orientation>()
                            {
                                first, second, third, fourth
                            };

                            if (orientations.Count(o => o == Orientation.Colinear) == 0 &&
                                first != second && third != fourth)
                            {
                                // ténylegesen metszik egymást
                                intersectCount++;
                            }
                            else if (orientations.Count(o => o == Orientation.Colinear) == 1)
                            {
                                if (first == Orientation.Colinear || second == Orientation.Colinear)
                                {
                                    //   o     o
                                    //    \    |
                                    //     \   |
                                    // o----o--o-o--o---------o helper
                                    //           |   \ 
                                    //           |    \
                                    //           o     o

                                    if (third != fourth)
                                    {
                                        //this condition should be always true
                                        //az éppen vizsgált él azon csúcsa, ami rajta van a helperen
                                        Point vertex = Vertices.Single(v => v.Y == helper.Start.Y && side.IsPartOfMe(v));
                                        // a vizsgált élhez az előbb megkapott csúcsban csatlakozó másik él
                                        //Side sideTwo = Sides.Single(s => (s.Start.Equals(vertex) || s.End.Equals(vertex)) && s.Id != side.Id);



                                        Side sideTwo = VisualSides.Single(s => (s.Start.Equals(vertex) || s.End.Equals(vertex)) && s.Id != side.Id);



                                        List <Point> pts = new List <Point>()
                                        {
                                            side.Start, side.End, sideTwo.Start, sideTwo.End
                                        };
                                        List <Point> pts2 = pts.Where(p => !p.Equals(vertex)).ToList();


                                        if (pts2.ElementAt(0).Y > helper.Start.Y && pts2.ElementAt(1).Y > helper.Start.Y)
                                        {
                                            //      o     o
                                            //       \   /
                                            //        \ /
                                            // o-------o-------------- helper
                                            //
                                            //
                                            //
                                            intersectCount += 2;
                                            side.Checked    = true;
                                            foreach (Side s in VisualSides)
                                            {
                                                if (s.Equals(sideTwo))
                                                {
                                                    s.Checked = true;
                                                }
                                            }
                                        }
                                        else if (pts2.ElementAt(0).Y < helper.Start.Y && pts2.ElementAt(1).Y < helper.Start.Y)
                                        {
                                            //
                                            //
                                            //
                                            // o--------o------------- helper
                                            //         / \ 
                                            //        /   \
                                            //       o     o
                                            intersectCount += 2;
                                            side.Checked    = true;
                                            foreach (Side s in VisualSides)
                                            {
                                                if (s.Equals(sideTwo))
                                                {
                                                    s.Checked = true;
                                                }
                                            }
                                        }
                                        else if (pts2.Any(v => v.Y == helper.Start.Y))
                                        {
                                            // itt a v-e1 él a vizsgált él, ha a e0-v lenne, akkor mind a négy colinear lenne
                                            //
                                            //    (e0)   v
                                            // o---o-----o------------- helper
                                            //            \ 
                                            //             \
                                            //              o (e1)

                                            //akkor hagyjuk az egészet és majd ez az oldal ott kerül feldolgozásra
                                            // ahol a vizzszintes oldalt vizsgáljuk és a két hozzá kapcsolódó élt
                                        }
                                        else
                                        {
                                            //ez az általános eset
                                            //      o
                                            //       \ 
                                            //        \ 
                                            // o-------o-------------- helper
                                            //        /
                                            //       /
                                            //      o
                                            intersectCount++;
                                            side.Checked = true;
                                            foreach (Side s in VisualSides)
                                            {
                                                if (s.Equals(sideTwo))
                                                {
                                                    s.Checked = true;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            else if (orientations.Count(o => o == Orientation.Colinear) == 4)
                            {
                                if (helper.Start.X < side.Start.X)
                                {
                                    //      o (connectedOne)
                                    //       \ 
                                    //        \ (side)
                                    // o-------o------o-------- helper
                                    //                |
                                    //                |
                                    //                o (connectedTwo)

                                    //Side connectedSideOne = Sides.Single(s => s.End.Equals(side.Start));
                                    //Side connectedSideTwo = Sides.Single(s => s.Start.Equals(side.End));



                                    Side connectedSideOne = VisualSides.Single(s => s.End.Equals(side.Start));
                                    Side connectedSideTwo = VisualSides.Single(s => s.Start.Equals(side.End));



                                    List <Point> pts = new List <Point>()
                                    {
                                        connectedSideOne.Start, connectedSideOne.End, connectedSideTwo.Start, connectedSideTwo.End
                                    };
                                    List <Point> pts2 = pts.Where(p => !p.Equals(side.Start) && !p.Equals(side.End)).ToList();

                                    if ((side.Start.Y < pts2.ElementAt(0).Y&& side.Start.Y < pts2.ElementAt(1).Y) ||
                                        (pts2.ElementAt(0).Y < side.Start.Y && pts2.ElementAt(1).Y < side.Start.Y))
                                    {
                                        //      o            o
                                        //       \          /
                                        //        \        /
                                        // o-------o------o---- helper
                                        //
                                        //
                                        //

                                        //
                                        //
                                        // o--------o------o-------- helper
                                        //         /        \
                                        //        /          \
                                        //       o            o
                                        intersectCount += 2;
                                    }
                                    else if (false)
                                    {
                                        //     ezek még nincsenek lekezelve
                                        //
                                        // o---o~~~~o~~~~~~o~~~~o---- helper
                                        //
                                        //
                                        //

                                        //      o
                                        //       \ 
                                        //        \
                                        // o-------o~~~~~~o~~~~o---- helper
                                        //
                                        //
                                        //

                                        //
                                        //
                                        // o---o~~~~o~~~~~~o-------- helper
                                        //                  \
                                        //                   \
                                        //                    o
                                    }
                                    else
                                    {
                                        //      o
                                        //       \ 
                                        //        \
                                        // o-------o-------o---- helper
                                        //                  \
                                        //                   \
                                        //                    o

                                        //                    o
                                        //                   /
                                        //                  /
                                        // o-------o-------o---- helper
                                        //        /
                                        //       /
                                        //      o

                                        intersectCount += 3;
                                    }

                                    side.Checked = true;
                                    foreach (Side s in VisualSides)
                                    {
                                        if (s.Equals(connectedSideOne) || s.Equals(connectedSideTwo))
                                        {
                                            s.Checked = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    intersectCount = 1;
                }


                if (intersectCount % 2 == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #2
0
 public bool Equals(Side side)
 {
     return((Start.Equals(side.Start) && End.Equals(side.End)) || (Start.Equals(side.End) && End.Equals(side.Start)));
 }
 private static Side OtherSide(Side side)
 {
     return(side == Side.Left ? Side.Right : Side.Left);
 }
        private NodeMeta SwapWithAdjacent(NodeMeta meta, Side side)
        {
            Side     otherSide      = OtherSide(side);
            NodeMeta adjacentMeta   = Adjacent(side, meta);
            Node     adjacent       = adjacentMeta.Node;
            Node     toBeReplaced   = meta.Node;
            Node     adjacentParent = adjacentMeta.ParentMeta.Node;

            // Swap the nodes.
            // Cache the children of item to be replaced.
            Node child = adjacent[side];

            bool parentChildSwap = toBeReplaced[side] == adjacent;

            // Adjacent takes place of node to be removed.
            meta.ReplaceNode(adjacent);
            if (meta.ParentMeta == null)
            {
                root = adjacent;
            }
            else
            {
                meta.ParentMeta.Node[meta.SideFromParent] = adjacent;
            }
            if (!parentChildSwap)
            {
                adjacent[side] = toBeReplaced[side];
            }
            adjacent[otherSide] = toBeReplaced[otherSide];

            // Put node to be replaced in adjacent spot
            if (parentChildSwap)
            {
                adjacent[otherSide] = toBeReplaced;
            }
            else
            {
                adjacentParent[otherSide] = toBeReplaced;
            }
            toBeReplaced[side]      = child;
            toBeReplaced[otherSide] = null; // This is null, that is how we know it is the leaf
            adjacentMeta.ReplaceNode(toBeReplaced);

            // Swap the color
            Color temp = toBeReplaced.Color;

            toBeReplaced.Color = adjacent.Color;
            adjacent.Color     = temp;
            if (meta.ParentMeta == null)
            {
                adjacent.Color = Color.Black;
            }

            if (child == null)
            {
                // We have found the node to remove. Replace it with a sentinal
                return(adjacentMeta);
            }
            else
            {
                return(SwapWithAdjacent(adjacentMeta, side));
            }
        }
        private void BalanceTree(NodeMeta meta)
        {
            if (meta == null)
            {
                return;
            }

            /* Five steps of any balance operation
             * 1) Extract relatives from meta data
             * 2) Decide on operation to perform
             * 3) Rotate as appropriate
             * 4) Change colors as appropriate
             * 5) Pass along metadata for next balance operation
             * */

            var      current    = meta.Node;
            var      parentMeta = meta.ParentMeta;
            NodeMeta nextMeta   = parentMeta;

            if (current.Color == Color.DoubleBlack)
            {
                Side otherSide      = OtherSide(meta.SideFromParent);
                Node distalNephew   = meta.Sibling[otherSide];
                Node proximalNephew = meta.Sibling[meta.SideFromParent];

                if (meta.Sibling.Color == Color.Black)
                {
                    if (distalNephew != null && distalNephew.Color == Color.Red)
                    {
                        nextMeta = RotateToChild(meta.SideFromParent, meta.ParentMeta);

                        RemoveDoubleBlack(meta);
                        meta.Sibling.Color = Color.Red;
                        distalNephew.Color = Color.Black;
                    }
                    else if (proximalNephew != null && proximalNephew.Color == Color.Red)
                    {
                        var siblingMeta = new NodeMeta(meta.ParentMeta, meta.Sibling, otherSide, current);
                        nextMeta = RotateToChild(otherSide, siblingMeta);

                        proximalNephew.Color = Color.Black;
                        meta.Sibling.Color   = Color.Red;

                        // Re-run this algorithm to process the distalNephew case.
                        nextMeta = meta;
                    }
                    else
                    {
                        RemoveDoubleBlack(meta);
                        meta.Sibling.Color = Color.Red;
                        var color = meta.ParentMeta.Node.Color == Color.Red ? Color.Black : Color.DoubleBlack;
                        meta.ParentMeta.Node.Color = color;
                        nextMeta = color == Color.DoubleBlack ? meta.ParentMeta : null;
                    }
                }
                else
                {
                    meta.Sibling.Color         = Color.Black;
                    meta.ParentMeta.Node.Color = Color.Red;

                    nextMeta = RotateToChild(meta.SideFromParent, meta.ParentMeta);

                    var gpmeta = nextMeta ?? new NodeMeta(root);
                    var pmeta  = new NodeMeta(gpmeta, meta.ParentMeta.Node, meta.SideFromParent, gpmeta.Node[otherSide]);
                    nextMeta = new NodeMeta(pmeta, meta.Node, meta.SideFromParent, meta.ParentMeta.Node[otherSide]);
                }
            }
            else if (current.Color == Color.Red)
            {
                if (parentMeta.Node.Color == Color.Red)
                {
                    if (parentMeta.Sibling != null && parentMeta.Sibling.Color == Color.Red)
                    {
                        // Papa and Uncle are Red, but Grandpa is black. Swap colors for everyone.
                        parentMeta.Sibling.Color = Color.Black;
                        parentMeta.Node.Color    = Color.Black;
                        SetRed(parentMeta.ParentMeta.Node);

                        // Skip a generation.
                        nextMeta = parentMeta.ParentMeta;
                    }
                    else if (meta.SideFromParent == parentMeta.SideFromParent)
                    {
                        // Handle Left-Left or Right-Right
                        //http://www.geeksforgeeks.org/red-black-tree-set-2-insert/
                        nextMeta = RotateToChild(OtherSide(meta.SideFromParent), parentMeta.ParentMeta);

                        var newSibling = parentMeta.ParentMeta.Node;
                        SetRed(newSibling);
                        meta.ParentMeta.Node.Color = Color.Black;
                    }
                    else
                    {
                        // Handle Left-Right or Right-Left
                        //http://www.geeksforgeeks.org/red-black-tree-set-2-insert/

                        // We know that our sibling is null
                        // We know that we have a grandparent.
                        nextMeta = RotateUpTwo(meta);
                        if (nextMeta == null)
                        {
                            SetRoot(meta.Node);
                        }

                        meta.Node.Color = Color.Black;
                        SetRed(meta.ParentMeta.ParentMeta.Node);
                    }
                }

                /* Node is red, and parent is black.
                 * If sibling is red, we can push the red up a node.
                 * This is not necessary, so I comment it out.
                 */

                //else if (meta.Sibling != null && meta.Sibling.Color == Color.Red) {
                //    meta.Node.Color = Color.Black;
                //    meta.Sibling.Color = Color.Black;
                //    SetRed(meta.ParentMeta.Node);
                //}
            }
            BalanceTree(nextMeta);
        }
 public virtual Node this[Side side] {
     get { return(children[(int)side]); }
     set { children[(int)side] = value; }
 }