Beispiel #1
0
        }                    // Default constructor

        public CQue(int len) // Constructor
        {
            Len    = len;
            input  = 0;
            output = 0;
            full   = false;
            Array  = new iVect2[Len];
            for (int i = 0; i < Len; i++)
            {
                Array[i] = new iVect2();
            }
        }
Beispiel #2
0
        }                                                  // Default constructor

        public CListLines(int maxL2, int maxV, int maxArc) // constructor
        {
            MaxPoly  = maxL2;
            MaxVert  = maxV;
            MaxArc   = maxArc;
            pQ       = new CQue(1000); // necessary to find connected components
            nArc     = 0;
            nPolygon = 0;
            Polygon  = new CPolygon[MaxPoly];
            int i = 0;

            for (i = 0; i < MaxPoly; i++)
            {
                Polygon[i] = new CPolygon();
            }
            Vert = new iVect2[MaxVert];
            for (i = 0; i < MaxVert; i++)
            {
                Vert[i] = new iVect2();
            }
            Arc = new CArc[MaxArc];
            for (i = 0; i < MaxArc; i++)
            {
                Arc[i] = new CArc();
            }
            Arc2 = new CArc2[MaxArc];
            for (i = 0; i < MaxArc; i++)
            {
                Arc2[i] = new CArc2();
            }
            Step = new iVect2[4];
            for (i = 0; i < 4; i++)
            {
                Step[i] = new iVect2();
            }
            Norm = new iVect2[4];
            for (i = 0; i < 4; i++)
            {
                Norm[i] = new iVect2();
            }

            Step[0].X = 1; Step[0].Y = 0;
            Step[1].X = 0; Step[1].Y = 1;
            Step[2].X = -1; Step[2].Y = 0;
            Step[3].X = 0; Step[3].Y = -1;

            Norm[0].X = 0; Norm[0].Y = 1;
            Norm[1].X = -1; Norm[1].Y = 0;
            Norm[2].X = 0; Norm[2].Y = -1;
            Norm[3].X = 1; Norm[3].Y = 0;
        } //*************** end constructor *********************
Beispiel #3
0
 public int Put(iVect2 V)
 {
     if (full)
     {
         return(-1);
     }
     Array[input] = V;
     if (input == Len - 1)
     {
         input = 0;
     }
     else
     {
         input++;
     }
     return(1);
 }
Beispiel #4
0
        } //***************************************** end TraceApp ***********************************************

        public int ComponPoly(CImage Comb, int X, int Y, double eps)

        /* Encodes in "CListLines" the polygones of the edge component with the point (X, Y) being
         * a branch or an end point. Puts the starting point 'Pinp' into the queue and starts
         * the 'while' loop. It tests each labeled crack incident to the point 'P' fetched from the queue.
         * If the next point of the crack is a branch or an end point, then crack is being ignorred.
         * Otherwise the funktion "TraceApp" is called. "TraceApp" traces the edge until the next end or
         * branch point and calulates the verices of the approximating polygon. The tracing ends at the
         * point 'Pterm' with the direction 'DirT'. If the point 'Pterm' is a branch point then it is put
         * to the queue. "ComponPoly" returns when the queue is empty.	---------------*/
        {
            int    dir, dirT;
            int    LabNext, rv;
            iVect2 Crack, P, Pinp, Pnext, Pterm;

            Crack  = new iVect2();
            P      = new iVect2();
            Pinp   = new iVect2();
            Pnext  = new iVect2();
            Pinp.X = X;
            Pinp.Y = Y; // comb. coord.
            int CNX = Comb.width;
            int CNY = Comb.height;

            pQ.Put(Pinp);
            while (!pQ.Empty()) //===========================================================================
            {
                P = pQ.Get();
                if ((Comb.Grid[P.X + CNX * P.Y] & 128) != 0)
                {
                    continue;
                }

                for (dir = 0; dir < 4; dir++) //================================================================
                {
                    Crack.X = P.X + Step[dir].X;
                    Crack.Y = P.Y + Step[dir].Y;
                    if (Crack.X < 0 || Crack.X > CNX - 1 || Crack.Y < 0 || Crack.Y > CNY - 1)
                    {
                        continue;
                    }
                    if (Comb.Grid[Crack.X + CNX * Crack.Y] == 1) //--------------------------------------
                    {
                        Pnext.X = Crack.X + Step[dir].X;
                        Pnext.Y = Crack.Y + Step[dir].Y;
                        LabNext = Comb.Grid[Pnext.X + CNX * Pnext.Y] & 7;

                        if (LabNext == 3)
                        {
                            pQ.Put(Pnext);
                        }
                        if (LabNext == 2) //--------------------------------------------------------------
                        {
                            Polygon[nPolygon].firstVert = nVert;
                            dirT  = dir;
                            Pterm = new iVect2();

                            rv = TraceApp(Comb, P.X, P.Y, eps, ref Pterm, ref dirT);
                            if (rv < 0)
                            {
                                MessageBox.Show("ComponPoly, Alarm! TraceApp returned " + rv + ". return -1.");
                                return(-1);
                            }
                            if (nPolygon > MaxPoly - 1)
                            {
                                MessageBox.Show("ComponPoly: Overflow in Polygon; nPolygon=" + nPolygon + " MaxPoly=" + MaxPoly);
                                return(-1);
                            }
                            else
                            {
                                nPolygon++;
                            }
                            if ((Comb.Grid[Pterm.X + CNX * Pterm.Y] & 128) == 0 && rv >= 3)
                            {
                                pQ.Put(Pterm);
                            }
                        } // ------------- end if (LabNest==2) -----------------------------------------------------
                        if ((Comb.Grid[P.X + CNX * P.Y] & 7) == 1)
                        {
                            break;
                        }
                    } //--------------- end if (Comb.Grid[Crack.X ...==1) ------------------------------------------
                }     //================================== end for (dir ... ==========================================
                Comb.Grid[P.X + CNX * P.Y] |= 128;
            }         //==================================== end while ==========================================
            return(1);
        }             //************************************** end ComponPoly ************************************************
Beispiel #5
0
        } //*************************** end CheckComb ************************************

        public int TraceApp(CImage Comb, int X, int Y, double eps, ref iVect2 Pterm, ref int dir)

        /* This method traces a line in the image "Comb" with combinatorial coordinates, where the cracks
         *      and points of the edges are labeled: bits 0 and 1 of a point contain the label 1 to 3 of the point.
         *      The label indicates the number of incident edge cracks. Bits 2 to 5 indicate the presence of
         *      incident cracks of directions 0, 1, 2 and 3 correspondingly. Labeled bit 6 indicates that the point
         *      already has been put into the queue; labeled bit 7 indicates that the point shoud not been used any more.
         *      The crack has only one label 1 in bit 0.
         *      This function traces the edge from one end or branch point to another while changing the parameter "dir".
         *      It makes polygonal approximation with precision "eps" and saves STANDARD coordinats in "Vert".
         *      ----------*/
        {
            int    br, Lab, rv = 0;
            bool   BP = false, END = false;
            bool   atSt_P = false, CHECK = true;
            iVect2 Crack, P, P1, Pold, Pstand, StartEdge, StartLine, Vect;

            Crack     = new iVect2();
            P         = new iVect2();
            P1        = new iVect2();
            Pold      = new iVect2();
            Pstand    = new iVect2();
            StartEdge = new iVect2();
            StartLine = new iVect2();
            Vect      = new iVect2();

            int iCrack = 0;

            P.X         = X; P.Y = Y;
            Pstand.X    = X / 2;
            Pstand.Y    = Y / 2;
            P1.X        = Pold.X = P.X;
            P1.Y        = Pold.Y = P.Y;
            StartEdge.X = X / 2;
            StartEdge.Y = Y / 2;
            StartLine.X = X / 2;
            StartLine.Y = Y / 2;

            int[] Shift = new int[4];
            Shift[0] = 0;
            Shift[1] = 2;
            Shift[2] = 4;
            Shift[3] = 6;

            Vert[nVert].X = Pstand.X;
            Vert[nVert].Y = Pstand.Y;
            nVert++;
            Vect = new iVect2();
            int CNX = Comb.width;
            int CNY = Comb.height;

            CheckComb(StartEdge, Pstand, eps, ref Vect);

            while (true) //====================================================================
            {
                Crack.X = P.X + Step[dir].X;
                Crack.Y = P.Y + Step[dir].Y;
                if (Comb.Grid[Crack.X + CNX * Crack.Y] == 0)
                {
                    MessageBox.Show("TraceApp, error: dir=" + dir + " the Crack=(" + Crack.X + "," + Crack.Y +
                                    ") has label 0;  X=" + X + ", Y=" + Y + "; iCrack=" + iCrack + " return -1");
                    MessageBox.Show("Point before Crack Lab=" + (Comb.Grid[P.X + CNX * P.Y] & 7) + " P+0=" + (Comb.Grid[P.X + 1 + CNX * P.Y] & 7) +
                                    " P+1=" + (Comb.Grid[P.X + CNX * (P.Y + 1)] & 7) + " P+2=" + (Comb.Grid[P.X - 1 + CNX * P.Y] & 7) +
                                    " P+3=" + (Comb.Grid[P.X + CNX * (P.Y - 1)] & 7));
                }
                P.X      = P1.X = Crack.X + Step[dir].X;
                P.Y      = P1.Y = Crack.Y + Step[dir].Y;
                Pstand.X = P.X / 2;
                Pstand.Y = P.Y / 2;

                br = CheckComb(StartEdge, Pstand, eps, ref Vect);

                Lab = Comb.Grid[P.X + CNX * P.Y] & 7;
                switch (Lab)
                {
                case 1: END = true; BP = false; rv = 1; break;

                case 2: BP = END = false; break;

                case 3: BP = true; END = false; rv = 3; break;

                case 4: BP = true; END = false; rv = 4; break;
                }
                if (Lab == 2)
                {
                    Comb.Grid[P.X + CNX * P.Y] = 0;   // deleting all labels of P
                }
                iCrack++;

                if (br > 0) //--------------------------------------------------------------
                {
                    if (nVert >= MaxVert - 1)
                    {
                        MessageBox.Show("TraceApp: Overflow in 'Vert'; X=" + X + " Y=" + Y + " nVert=" + nVert);
                        return(-1);
                    }
                    if (CHECK) //-------------------------------------------
                    {
                        if (br == 1)
                        {
                            Vert[nVert].X = Pold.X / 2;
                            Vert[nVert].Y = Pold.Y / 2;
                        }
                        else
                        {
                            Vert[nVert] = Vect;
                        }
                        StartEdge = Vert[nVert];
                    }
                    else // CHECK == false
                    {
                        if (br == 10)
                        {
                            Vert[nVert].X = Pold.X / 2;
                            Vert[nVert].Y = Pold.Y / 2;
                        }
                        else
                        {
                            Vert[nVert] = P1;
                        }
                    } //----------------------------- end if (CHECK) ------------------------------

                    br = 0;
                    nVert++;
                } //------------------ end if (br) --------------------------------------

                atSt_P = (Pstand == StartLine);
                if (atSt_P)
                {
                    Pterm.X = P.X; // Pterm is a parameter of TraceApp
                    Pterm.Y = P.Y;
                    Polygon[nPolygon].lastVert = nVert - 1;
                    Polygon[nPolygon].closed   = true;
                    rv = 2;
                    break;
                }

                if (!atSt_P && (BP || END))
                {
                    Pterm.X       = P.X; // Pterm is a parameter of TraceApp
                    Pterm.Y       = P.Y;
                    Vert[nVert].X = Pstand.X;
                    Vert[nVert].Y = Pstand.Y;

                    Polygon[nPolygon].lastVert = nVert;
                    Polygon[nPolygon].closed   = false;
                    nVert++;
                    if (BP)
                    {
                        rv = 3;
                    }
                    else
                    {
                        rv = 1;
                    }
                    break;
                }

                if (!BP && !END) //---------------------------
                {
                    Crack.X = P.X + Step[(dir + 1) % 4].X;
                    Crack.Y = P.Y + Step[(dir + 1) % 4].Y;
                    if (Comb.Grid[Crack.X + CNX * Crack.Y] == 1)
                    {
                        dir = (dir + 1) % 4;
                    }
                    else
                    {
                        Crack.X = P.X + Step[(dir + 3) % 4].X;
                        Crack.Y = P.Y + Step[(dir + 3) % 4].Y;
                        if (Comb.Grid[Crack.X + CNX * Crack.Y] == 1)
                        {
                            dir = (dir + 3) % 4;
                        }
                    }
                }
                else
                {
                    break;
                }
                Pold.X = P.X;
                Pold.Y = P.Y;
            } //======================================= end while ============================================
            Polygon[nPolygon].nCrack = iCrack;
            return(rv);
        } //***************************************** end TraceApp ***********************************************
Beispiel #6
0
        } //****************************** end SearchPoly ********************************

        int CheckComb(iVect2 StartP, iVect2 P, double eps, ref iVect2 Vect)
        // This is the new function for polygonal approximation with the sector method.
        // It replaces the old function "secomb"; 'P' is in standard coord.
        {
            double Length, Sin, Cos, Proj, PosTangX, PosTangY, NegTangX, NegTangY;
            iVect2 Line = new iVect2();

            if (StartP == P)
            {
                PosSectX = -1000.0;
                return(0);
            }
            Line.X = P.X - StartP.X;
            Line.Y = P.Y - StartP.Y;
            Length = Math.Sqrt(Math.Pow((double)Line.X, 2.0) + Math.Pow((double)Line.Y, 2.0));
            if (Length < eps)
            {
                return(0);
            }

            if (PosSectX == -1000.0)
            {
                Sin      = eps / Length;
                Cos      = Math.Sqrt(1.0 - Sin * Sin);
                PosSectX = Line.X * Cos - Line.Y * Sin;
                PosSectY = Line.X * Sin + Line.Y * Cos;
                NegSectX = Line.X * Cos + Line.Y * Sin;
                NegSectY = -Line.X * Sin + Line.Y * Cos;
                Far      = P;
                return(0);
            }

            Proj = (double)((Far.X - StartP.X) * (P.X - Far.X) + (Far.Y - StartP.Y) * (P.Y - Far.Y));
            if (Proj < -eps * Math.Sqrt(Math.Pow((double)(Far.X - StartP.X), 2.0) + Math.Pow((double)(Far.Y - StartP.Y), 2.0)))
            {
                Vect     = Far;
                PosSectX = -1000.0;
                return(2);
            }
            if (Proj >= 0.0)
            {
                Far = P;
            }

            if (PosSectX * Line.Y - PosSectY * Line.X > 0.0 || NegSectX * Line.Y - NegSectY * Line.X < 0.0)
            {
                PosSectX = -1000.0;
                return(1);
            }


            if (PosSectX != -1000.0 && Length > eps)
            {
                Sin      = eps / Length; Cos = Math.Sqrt(1 - Sin * Sin);
                PosTangX = Line.X * Cos - Line.Y * Sin;
                PosTangY = Line.X * Sin + Line.Y * Cos;
                NegTangX = Line.X * Cos + Line.Y * Sin;
                NegTangY = -Line.X * Sin + Line.Y * Cos;

                if (NegSectX * NegTangY - NegSectY * NegTangX > 0.0)
                {
                    NegSectX = NegTangX;
                    NegSectY = NegTangY;
                }
                if (PosSectX * PosTangY - PosSectY * PosTangX < 0.0)
                {
                    PosSectX = PosTangX;
                    PosSectY = PosTangY;
                }
            }
            return(0);
        } //*************************** end CheckComb ************************************