예제 #1
0
 /************************************************************
 *  CONSTRUCTORS/DESTRUCTORS AND FIELD MANIPULATORS          *
 ************************************************************/
 public ClosestPair()
 {
     InitializeComponent();
     X_MAX = Panel1.Width + 10;
     Y_MAX = Panel1.Height + 10;
     DELAY = 100;
     North = new PointSet();
     South = new PointSet();
     East = new PointSet();
     West = new PointSet();
     rand = new Random();
     isSplit = new System.Drawing.Point();
 }
예제 #2
0
        public double ClosestPairDQ(PointSet S, ref PointSet current)
        {
            if (S.points.Count <= 1)
            {
                S.dmin = inf;
            }
            else
            {
                // calculate co-ordinates of median point
                int median = (int)Math.Ceiling((decimal)S.points.Count / 2);
                Point M = S.pointAt(median - 1);

                // calculate two subproblems (median in first subset)
                PointSet S1 = subSet(S, 0, median - 1);
                PointSet S2 = subSet(S, median, S.points.Count - 1);

                // highlight the whole set
                if (DELAY > 50)
                {
                    drawField(S, Color.Cyan);
                    drawVertical(M, Color.Blue);
                    pause(DELAY);
                    eraseVertical(M);
                    eraseField(S);
                }

                // recursively calculate solutions to sub-problems
                S.dmin = Math.Min(ClosestPairDQ(S1, ref current), ClosestPairDQ(S2, ref current));

                // highlight the whole set, and solutions for each subset
                if (DELAY > 50)
                {
                    drawField(S, Color.Cyan);
                    drawVertical(M, Color.Blue);
                    pause(DELAY);
                }

                // merge two sub-solutions
                S = merge(S, S1, S2, ref current);

                // highlight set in gray b/c solution has been computed
                if (DELAY > 50)
                {
                    eraseVertical(M);
                    eraseField(S);
                    drawField(S, Color.LightGray);
                    pause(DELAY);
                }
            }
            return S.dmin;
        }
예제 #3
0
 public ClosestPair(int delay)
 {
     InitializeComponent();
     X_MAX = Panel1.Width;
     Y_MAX = Panel1.Height;
     DELAY = delay;
     North = new PointSet();
     South = new PointSet();
     East = new PointSet();
     West = new PointSet();
     rand = new Random();
     distance.Left = 0;
     distance.Top = 0;
     isSplit = new System.Drawing.Point();
 }
예제 #4
0
        // Test a point Q in P's bounding box
        PointSet testBoundingBoxPoint(PointSet S, Point P, Point Q)
        {
            double d = dist(P, Q);

                if (d < S.dmin)
                {

                    // update minimal distance
                    S.dmin = d;
                    if (S.closestPair.Count == 0)
                    {
                        S.closestPair.Add(P);
                        S.closestPair.Add(Q);
                    }
                    else
                    {
                        S.closestPair[0] = P;
                        S.closestPair[1] = Q;
                    }

                    // flash the segment to show that a new minimal distance was found
                    if (DELAY > 50)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            eraseSegment(P, Q, Color.Yellow);
                            pause((int)(DELAY / 2));
                            drawSegment(P, Q);
                            pause((int)(DELAY / 2));
                        }
                    }
                }

            return S;
        }
예제 #5
0
 /***********************************************************************
 *  DIVIDE-AND-CONQUER ALGORITHM + FUNCTIONS                            *
 ***********************************************************************/
 public double ClosestPairDQ(PointSet S)
 {
     return ClosestPairDQ(S, ref S);
 }
예제 #6
0
        private bool SameColor(PointSet ps)
        {
            if (ps.closestPair.Count > 1)
            {
                if (ps.closestPair[0].color == ps.closestPair[1].color)
                    return true;
            }

            return false;
        }
예제 #7
0
        private void Panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Point p;
                if (isSplit.X != 0)
                {
                    if (radioButton1.Checked)
                    {
                        p = new Point(e.X, e.Y, 0);
                    }
                    else if (radioButton2.Checked)
                    {
                        p = new Point(e.X, e.Y, 1);
                    }
                    else
                    {
                        p = new Point(e.X, e.Y, rand.Next(0, 2));
                    }

                    if (e.X > 0 && e.X < isSplit.X)
                    {
                        //west
                        if (e.Y > 0 && e.Y < isSplit.Y)
                        {
                            North.add(p);
                        }
                        else
                        {
                            West.add(p);
                        }
                    }
                    else
                    {
                        //east
                        if (e.Y > 0 && e.Y < isSplit.Y)
                        {
                            East.add(p);
                        }
                        else
                        {
                            South.add(p);
                        }
                    }
                }
                else
                {
                    if (radioButton1.Checked)
                    {
                        p = new Point(e.X, e.Y, 0);
                    }
                    else if (radioButton2.Checked)
                    {
                        p = new Point(e.X, e.Y, 1);
                    }
                    else
                    {
                        p = new Point(e.X, e.Y, rand.Next(0, 2));
                    }
                    North.add(p);
                }
                drawPoint(p);
            }
            else if (e.Button == MouseButtons.Right)
            {
                if (isSplit.X == 0)
                {
                    isSplit.X = e.X;
                    isSplit.Y = e.Y;
                    Graphics g = Panel1.CreateGraphics();
                    Pen p = new Pen(Color.Black);
                    g.DrawLine(p, 0, e.Y, e.X, e.Y);
                    g.DrawLine(p, e.X, 0, e.X, e.Y);
                    g.DrawLine(p, e.X, e.Y, e.X, Panel1.Height);
                    g.DrawLine(p, e.X, e.Y, Panel1.Width, e.Y);

                    PointSet temp = new PointSet();
                    temp.points.AddRange(North.points);
                    North.points.Clear();
                    foreach (Point point in temp.points)
                    {
                        if (point.x > 0 && point.x < isSplit.X)
                        {
                            //west
                            if (point.y > 0 && point.y < isSplit.Y)
                            {
                                North.add(point);
                            }
                            else
                            {
                                West.add(point);
                            }
                        }
                        else
                        {
                            //east
                            if (point.y > 0 && point.y < isSplit.Y)
                            {
                                East.add(point);
                            }
                            else
                            {
                                South.add(point);
                            }
                        }
                    }
                }
            }
        }
예제 #8
0
        PointSet merge(PointSet S, PointSet S1, PointSet S2, ref PointSet WorkSet)
        {
            Point M = S1.pointAt(S1.points.Count - 1);

            // draw the strip about the median
            if (DELAY > 50)
            {
                drawDQStrip(S, M);
                pause(DELAY);
            }

            for (int i = 0; i < S.points.Count; i++)
            {
                Point P = S.pointAt(i);
                if (Math.Abs(P.x - M.x) <= S.dmin)
                {

                    // P is in S1, only look in S2
                    if (S1.contains(P))
                    {
                        S = testStripPoint(S, P, S2, M, true);
                    }

                    // P is in S2, only look in S1
                    if (S2.contains(P))
                    {
                        S = testStripPoint(S, P, S1, M, false);
                    }

                    // update miniMUM distance
                    if (S.dmin < WorkSet.dmin)
                    {

                        WorkSet.dmin = S.dmin;
                        if (WorkSet.closestPair.Count == 0)
                        {
                            WorkSet.closestPair.Add(S.closestPair[0]);
                            WorkSet.closestPair.Add(S.closestPair[1]);
                        }
                        else
                        {
                            WorkSet.closestPair[0] = S.closestPair[0];
                            WorkSet.closestPair[1] = S.closestPair[1];
                        }

                    }

                }
            }
            return S;
        }
예제 #9
0
        /************************************************************
        *  GRAPHICS FUNCTIONS FOR THE DIVIDE AND CONQUER ALGORITHM  *
        ************************************************************/
        public void drawDQStrip(PointSet S, Point M)
        {
            Graphics g = Panel1.CreateGraphics();
            int x, w;

            // set x
            if ((M.x - S.dmin) < S.first().x) { x = S.first().x; }
            else { x = M.x - ((int)S.dmin); }

            // set w
            if ((M.x + S.dmin) > S.last().x) { w = S.last().x - x; }
            else { w = M.x + ((int)S.dmin) - x; }

            SolidBrush brush = new SolidBrush(Color.Pink);
            g.FillRectangle(brush, x, 0, w, Y_MAX);
            drawVertical(M, Color.Blue);
            drawPoints(S, Color.Black);
        }
예제 #10
0
        private void findMidPoint(int x, int y)
        {
            if (x <= Panel1.Width || y <= Panel1.Height)
            {
                if (pairs() >= 4)
                {
                    PointSet tempNorth = new PointSet();
                    PointSet tempSouth = new PointSet();
                    PointSet tempEast = new PointSet();
                    PointSet tempWest = new PointSet();
                    System.Drawing.Point temp = new System.Drawing.Point(x, y);
                    PointSet tempSet = new PointSet();
                    tempSet.points.AddRange(North.points);
                    //North.points.Clear();
                    foreach (Point point in tempSet.points)
                    {
                        if (point.x > 0 && point.x < temp.X)
                        {
                            //west
                            if (point.y > 0 && point.y < temp.Y)
                            {
                                tempNorth.add(point);
                            }
                            else
                            {
                                tempWest.add(point);
                            }
                        }
                        else
                        {
                            //east
                            if (point.y > 0 && point.y < temp.Y)
                            {
                                tempEast.add(point);
                            }
                            else
                            {
                                tempSouth.add(point);
                            }
                        }
                    }
                    double distancePointsNorth = ClosestPairDQ(tempNorth);
                    double distancePointsSouth = ClosestPairDQ(tempSouth);
                    double distancePointsEast = ClosestPairDQ(tempEast);
                    double distancePointsWest = ClosestPairDQ(tempWest);

                    if (SameColor(tempNorth) && SameColor(tempEast) && SameColor(tempSouth) && SameColor(tempWest))
                    {

                        if (!Double.IsInfinity(distancePointsEast) && !Double.IsInfinity(distancePointsNorth)
                            && !Double.IsInfinity(distancePointsSouth) && !Double.IsInfinity(distancePointsWest))
                        {
                            isSplit = temp;
                            Graphics g = Panel1.CreateGraphics();
                            Pen p = new Pen(Color.Black);
                            g.DrawLine(p, 0, isSplit.Y, isSplit.X, isSplit.Y);
                            g.DrawLine(p, isSplit.X, 0, isSplit.X, isSplit.Y);
                            g.DrawLine(p, isSplit.X, isSplit.Y, isSplit.X, Panel1.Height);
                            g.DrawLine(p, isSplit.X, isSplit.Y, Panel1.Width, isSplit.Y);
                            tempSet.points.Clear();
                            tempSet.points.AddRange(North.points);
                            North.points.Clear();
                            foreach (Point point in tempSet.points)
                            {
                                if (point.x > 0 && point.x < isSplit.X)
                                {
                                    //west
                                    if (point.y > 0 && point.y < isSplit.Y)
                                    {
                                        North.add(point);
                                    }
                                    else
                                    {
                                        West.add(point);
                                    }
                                }
                                else
                                {
                                    //east
                                    if (point.y > 0 && point.y < isSplit.Y)
                                    {
                                        East.add(point);
                                    }
                                    else
                                    {
                                        South.add(point);
                                    }
                                }
                            }
                        }
                        else
                        {
                            System.Drawing.Point point;
                            if (tempEast.points.Count > tempNorth.points.Count)
                            {
                                if (tempEast.points.Count > tempSouth.points.Count)
                                {
                                    if (tempEast.points.Count > tempWest.points.Count)
                                        point = findAverage(tempEast, temp);
                                    else
                                        point = findAverage(tempWest, temp);
                                }
                                else if (tempSouth.points.Count > tempWest.points.Count)
                                    point = findAverage(tempSouth, temp);
                                else
                                    point = findAverage(tempWest, temp);
                            }
                            else if (tempNorth.points.Count > tempSouth.points.Count)
                            {
                                if (tempNorth.points.Count > tempWest.points.Count)
                                    point = findAverage(tempNorth, temp);
                                else
                                    point = findAverage(tempWest, temp);
                            }
                            else if (tempSouth.points.Count > tempWest.points.Count)
                            {
                                point = findAverage(tempSouth, temp);
                            }
                            else
                            {
                                point = findAverage(tempWest, temp);
                            }
                            findMidPoint(point.X, point.Y);
                        }
                    }
                    else
                    {
                        //niet dezelfde kleur
                    }
                }
                else
                {
                    //niet genoeg paren
                }
            }
            else
            {
                //niet gevonden
            }
        }
예제 #11
0
        private System.Drawing.Point findAverage(PointSet ps, System.Drawing.Point point)
        {
            int tempx = 0;
            int tempy = 0;
            foreach (Point p in ps.points)
            {
                tempx += p.x;
                tempy += p.y;
            }
            tempx = tempx / ps.points.Count;
            tempy = tempy / ps.points.Count;
            if (lastPoint.X == tempx && lastPoint.Y == tempy)
            {
                lastPoint = point;
                homePoint.X = rand.Next(0, Panel1.Width);
                homePoint.Y = rand.Next(0, Panel1.Height);

                return homePoint;
            }
            else
            {
                lastPoint = point;
                return new System.Drawing.Point(tempx, tempy);
            }
        }
예제 #12
0
 // returns a subset of containing the elements of S from fromIndex to
 // toIndex inclusive
 public PointSet subSet(PointSet S, int fromIndex, int toIndex)
 {
     PointSet T = new PointSet();
     for (int i = fromIndex; i <= toIndex; i++)
     {
         T.add(S.pointAt(i));
     }
     return T;
 }
예제 #13
0
 public void reset()
 {
     North = new PointSet();
     South = new PointSet();
     West = new PointSet();
     East = new PointSet();
     Graphics g = Panel1.CreateGraphics();
     SolidBrush brush = new SolidBrush(Color.White);
     g.FillRectangle(brush, 0, 0, X_MAX, Y_MAX);
     distance.Text = "";
 }
예제 #14
0
        public void eraseField(PointSet S)
        {
            Graphics g = Panel1.CreateGraphics();
            int w, x;

            x = S.first().x;
            w = S.last().x - x;

            SolidBrush brush = new SolidBrush(Color.White);
            g.FillRectangle(brush, x, 0, w, Y_MAX);
            drawPoints(S, Color.Black);
        }
예제 #15
0
 public void drawPoints(PointSet S, Color c)
 {
     for (int i = 0; i < S.points.Count; i++)
     {
         Point P = S.pointAt(i);
         drawPoint(P);
     }
 }
예제 #16
0
        // Test for closest pairs to P in set sS (P is a point in the strip)
        PointSet testStripPoint(PointSet S, Point P,
            PointSet sS, Point M, Boolean lookDIR)
        {
            Point Q;

            // Draw P's bounding box
            if (DELAY > 50)
            {
                drawDQBoundingBox(S, P, M, lookDIR);
                pause(DELAY);
            }

            for (int j = 0; j < sS.points.Count; j++)
            {
                Q = sS.pointAt(j);

                // if Q is in P's bounding box
                //if ((Math.Abs(P.x - Q.x) <= S.dmin) &&
                //(Math.Abs(P.y - Q.y) <= S.dmin))
                //{

                // draw a red segment to show that it is being compared
                if (DELAY > 50)
                {
                    drawSegment(P, Q);
                    pause(DELAY);
                }

                numComparisons++;
                S = testBoundingBoxPoint(S, P, Q);

                // erase the red segment after the comparison
                if (DELAY > 50)
                {
                    eraseSegment(P, Q, Color.Yellow);
                    pause(DELAY);
                }

                //}
            }

            // Erase P's bounding box
            if (DELAY > 50) { drawDQStrip(S, M); }

            return S;
        }
예제 #17
0
        public void drawDQBoundingBox(PointSet S, Point P, Point M, Boolean lookR)
        {
            Graphics g = Panel1.CreateGraphics();
            int x, y, w, h;

            // set x
            if (lookR == true) { x = P.x; }
            else
            {
                if ((P.x - S.dmin) < S.first().x) { x = S.first().x; }
                else { x = P.x - ((int)S.dmin); }
            }

            // set y
            if ((P.y - S.dmin) < 0) { y = 0; }
            else { y = P.y - ((int)S.dmin); }

            // set w
            if (lookR == true)
            {
                if ((x + S.dmin) > S.last().x) { w = S.last().x - x; }
                else { w = ((int)S.dmin); }
            }
            else
            {
                w = P.x - x;
            }

            // set h
            if ((P.y + S.dmin) > Y_MAX) { h = Y_MAX - y; }
            else { h = P.y + ((int)S.dmin) - y; }

            SolidBrush brush = new SolidBrush(Color.Yellow);
            g.FillRectangle(brush, x, y, w, h);
            drawVertical(M, Color.Blue);
            drawPoints(S, Color.Black);
        }