public int R(int x0, int y0) { int iv, x, xmax = 0, xold, y, yold; int sizeV = 9; iVect2[] Vert = new iVect2[sizeV]; Vert[0] = new iVect2(0, 18); Vert[1] = new iVect2(0, 0); Vert[2] = new iVect2(6, 0); Vert[3] = new iVect2(9, 2); Vert[4] = new iVect2(9, 5); Vert[5] = new iVect2(6, 9); Vert[6] = new iVect2(0, 9); Vert[7] = new iVect2(6, 9); Vert[8] = new iVect2(10, 18); // "-" xmax = xold = Vert[0].X; yold = Vert[0].Y; for (iv = 1; iv < sizeV; iv++) { x = Vert[iv].X; y = Vert[iv].Y; if (x > xmax) { xmax = x; } g.DrawLine(myPen, marginX + x0 + (int)(Zoom * xold), marginY + y0 + (int)(Zoom * yold), marginX + x0 + (int)(Zoom * x), marginY + y0 + (int)(Zoom * y)); xold = x; yold = y; } return(x0 + (int)(Zoom * (xmax + 6))); }
public int F9(int x0, int y0) { int iv, x, xmax = 0, xold, y, yold; const int sizeV = 12; iVect2[] Vert = new iVect2[sizeV]; Vert[0] = new iVect2(0, 18); Vert[1] = new iVect2(3, 16); Vert[2] = new iVect2(7, 10); Vert[3] = new iVect2(9, 6); Vert[4] = new iVect2(9, 3); Vert[5] = new iVect2(6, 0); Vert[6] = new iVect2(3, 0); Vert[7] = new iVect2(0, 3); Vert[8] = new iVect2(0, 8); Vert[9] = new iVect2(3, 11); Vert[10] = new iVect2(6, 11); Vert[11] = new iVect2(7, 10); // "6" xmax = xold = Vert[0].X; yold = Vert[0].Y; for (iv = 1; iv < sizeV; iv++) { x = Vert[iv].X; y = Vert[iv].Y; if (x > xmax) { xmax = x; } g.DrawLine(myPen, marginX + x0 + (int)(Zoom * xold), marginY + y0 + (int)(Zoom * yold), marginX + x0 + (int)(Zoom * x), marginY + y0 + (int)(Zoom * y)); xold = x; yold = y; } return(x0 + (int)(Zoom * (xmax + 6))); }
public int F7(int x0, int y0) { int iv, x, xmax = 0, xold, y, yold; const int sizeV = 4; iVect2[] Vert = new iVect2[sizeV]; Vert[0] = new iVect2(5, 18); Vert[1] = new iVect2(9, 0); Vert[2] = new iVect2(2, 0); Vert[3] = new iVect2(2, 2); // "7" xmax = xold = Vert[0].X; xmax = 0; xold = Vert[0].X; yold = Vert[0].Y; for (iv = 1; iv < sizeV; iv++) { x = Vert[iv].X; y = Vert[iv].Y; if (x > xmax) { xmax = x; } g.DrawLine(myPen, marginX + x0 + (int)(Zoom * xold), marginY + y0 + (int)(Zoom * yold), marginX + x0 + (int)(Zoom * x), marginY + y0 + (int)(Zoom * y)); xold = x; yold = y; } return(x0 + (int)(Zoom * (xmax + 7))); }
public CListCode() // Constructor { this.Step = new iVect2[4]; for (int i = 0; i < 4; i++) { Step[i] = new iVect2(); } this.Step[0].X = 1; this.Step[0].Y = 0; this.Step[1].X = 0; this.Step[1].Y = 1; this.Step[2].X = -1; this.Step[2].Y = 0; this.Step[3].X = 0; this.Step[3].Y = -1; }
} // Default constructor public CListLines(int max1, int max2, int maxB, int cnx, int cny, int nbits3) // constructor { this.MaxLine1 = max1; this.MaxLine2 = max2; this.MaxByte = maxB; this.CNX = cnx; this.CNY = cny; this.nBits3 = nbits3; this.pQ = new CQue(1000); // necessary to find connected components this.nLine1 = 0; this.nLine2 = 0; this.nByte = 0; this.Line1 = new CCrack[MaxLine1]; for (int i = 0; i < MaxLine1; i++) { Line1[i] = new CCrack(); } this.Line = new CLine[MaxLine2]; for (int i = 0; i < MaxLine2; i++) { Line[i] = new CLine(); } this.Step = new iVect2[4]; for (int i = 0; i < 4; i++) { Step[i] = new iVect2(); } this.Norm = new iVect2[4]; for (int 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; this.Line[0].EndByte = 0; this.Byte = new byte[MaxByte]; this.IndPos = new byte[MaxByte]; this.IndNeg = new byte[MaxByte]; } //*************** end constructor *********************/
public int Put(iVect2 V) { if (full) { return(-1); } Array[input] = V; if (input == Len - 1) { input = 0; } else { input++; } return(1); }
public CListCode(int nx, int ny, int nbits, CListLines L) // Constructor { this.width = nx; //nLine1, nLine2, nByte; this.height = ny; this.nBits = nbits; this.nLine1 = L.nLine1; this.Line1 = new CCrack[nLine1]; for (int i = 0; i < nLine1; i++) { Line1[i] = new CCrack(); } this.nLine2 = L.nLine2; this.Line = new CLine[nLine2]; for (int i = 0; i < nLine2; i++) { Line[i] = new CLine(); } this.nByte = L.nByte; this.Byte = new byte[nByte]; this.Corner = new byte[4]; this.Param = new int[6]; this.Param[0] = nx; this.Param[1] = ny; this.Param[2] = nbits; this.Param[3] = L.nLine1; this.Param[4] = L.nLine2; this.Param[5] = L.nByte; this.Step = new iVect2[4]; for (int i = 0; i < 4; i++) { Step[i] = new iVect2(); } this.Step[0].X = 1; this.Step[0].Y = 0; this.Step[1].X = 0; this.Step[1].Y = 1; this.Step[2].X = -1; this.Step[2].Y = 0; this.Step[3].X = 0; this.Step[3].Y = -1; }
public int Equal(int x0, int y0) { int x, xmax = 0, xold, y, yold; const int sizeV = 4; iVect2[] Vert = new iVect2[sizeV]; Vert[0] = new iVect2(1, 11); Vert[1] = new iVect2(11, 11); Vert[2] = new iVect2(1, 7); Vert[3] = new iVect2(11, 7); // "=" xmax = 10; xold = Vert[0].X; yold = Vert[0].Y; x = Vert[1].X; y = Vert[1].Y; g.DrawLine(myPen, marginX + x0 + (int)(Zoom * xold), marginY + y0 + (int)(Zoom * yold), marginX + x0 + (int)(Zoom * x), marginY + y0 + (int)(Zoom * y)); xold = Vert[2].X; yold = Vert[2].Y; x = Vert[3].X; y = Vert[3].Y; g.DrawLine(myPen, marginX + x0 + (int)(Zoom * xold), marginY + y0 + (int)(Zoom * yold), marginX + x0 + (int)(Zoom * x), marginY + y0 + (int)(Zoom * y)); return(x0 + (int)(Zoom * (xmax + 6))); }
public iVect2 Get() { iVect2 er = new iVect2(-1, -1); if (Empty()) { return(er); } iVect2 iV = Array[output]; if (output == Len - 1) { output = 0; } else { output++; } if (full) { full = false; } return(iV); }
public int Minus(int x0, int y0) { int iv, x, xmax = 0, xold, y, yold; int sizeV = 2; //iVect2[] Vert = { {2, 9), {10, 9) }; // "-" iVect2[] Vert = new iVect2[sizeV]; Vert[0] = new iVect2(2, 9); Vert[1] = new iVect2(10, 9); // "-" xold = Vert[0].X; yold = Vert[0].Y; for (iv = 1; iv < sizeV; iv++) { x = Vert[iv].X; y = Vert[iv].Y; if (x > xmax) { xmax = x; } g.DrawLine(myPen, marginX + x0 + (int)(Zoom * xold), marginY + y0 + (int)(Zoom * yold), marginX + x0 + (int)(Zoom * x), marginY + y0 + (int)(Zoom * y)); xold = x; yold = y; } return(x0 + (int)(Zoom * (xmax + 6))); } //*************************** end Minus ****************************
public int U(int x0, int y0) { int iv, x, xmax = 0, xold, y, yold; const int sizeV = 6; iVect2[] Vert = new iVect2[sizeV]; Vert[0] = new iVect2(0, 0); Vert[1] = new iVect2(0, 15); Vert[2] = new iVect2(3, 18); Vert[3] = new iVect2(7, 18); Vert[4] = new iVect2(10, 15); Vert[5] = new iVect2(10, 0); xmax = xold = Vert[0].X; yold = Vert[0].Y; for (iv = 1; iv < sizeV; iv++) { x = Vert[iv].X; y = Vert[iv].Y; if (x > xmax) { xmax = x; } g.DrawLine(myPen, marginX + x0 + (int)(Zoom * xold), marginY + y0 + (int)(Zoom * yold), marginX + x0 + (int)(Zoom * x), marginY + y0 + (int)(Zoom * y)); xold = x; yold = y; } return(x0 + (int)(Zoom * (xmax + 6))); }
} //*************************** end Minus **************************** public int Plus(int x0, int y0) { int iv, x, xmax = 0, xold, y, yold; int sizeV = 5; iVect2[] Vert = new iVect2[sizeV]; Vert[0] = new iVect2(0, 9); Vert[1] = new iVect2(12, 9); Vert[2] = new iVect2(6, 9); Vert[3] = new iVect2(6, 15); Vert[4] = new iVect2(6, 3); // "+" xold = Vert[0].X; yold = Vert[0].Y; for (iv = 1; iv < sizeV; iv++) { x = Vert[iv].X; y = Vert[iv].Y; if (x > xmax) { xmax = x; } g.DrawLine(myPen, marginX + x0 + (int)(Zoom * xold), marginY + y0 + (int)(Zoom * yold), marginX + x0 + (int)(Zoom * x), marginY + y0 + (int)(Zoom * y)); xold = x; yold = y; } return(x0 + (int)(Zoom * (xmax + 6))); } //*************************** end Minus ****************************
} //**************************** end Transform ******************************************** public int Restore(ref CImage Image, ref CImage Mask, Form1 fm1) // Calculates the colors at the borders of the image and along the lines. Constructs the image Mask. { int c, dir, i, il, LabMask = 250, nComp, x, y; if (nBits == 24) { nComp = 3; } else { nComp = 1; } for (i = 0; i < width * height * nBits / 8; i++) { Image.Grid[i] = 0; } for (i = 0; i < width * height; i++) { Mask.Grid[i] = 0; } // Setting the corners if (nBits == 24) { for (c = 0; c < nComp; c++) { Image.Grid[c] = (byte)((Palette[Corner[0]] >> 8 * (2 - c)) & 0XFF); // left below } for (c = 0; c < nComp; c++) { Image.Grid[nComp * (width - 1) + c] = (byte)((Palette[Corner[1]] >> 8 * (2 - c)) & 0XFF); // right below } for (c = 0; c < nComp; c++) { Image.Grid[nComp * width * height - nComp + c] = (byte)((Palette[Corner[2]] >> 8 * (2 - c)) & 0XFF); // right on top } for (c = 0; c < nComp; c++) { Image.Grid[nComp * width * (height - 1) + c] = (byte)((Palette[Corner[3]] >> 8 * (2 - c)) & 0XFF); // left on top } } else { Image.Grid[0] = Corner[0]; Image.Grid[width - 1] = Corner[1]; Image.Grid[width * height - 1] = Corner[2]; Image.Grid[0 + width * (height - 1)] = Corner[3]; } Mask.Grid[0] = Mask.Grid[width - 1] = Mask.Grid[width * height - 1] = Mask.Grid[width * (height - 1)] = (byte)LabMask; // Short lines: fm1.progressBar1.Value = 0; fm1.progressBar1.Step = 1; fm1.progressBar1.Visible = true; int jump, nStep = 20; if (nLine1 > 2 * nStep) { jump = nLine1 / nStep; } else { jump = 2; } for (il = 0; il < nLine1; il++) //===================================================== { if ((il % jump) == jump - 1) { fm1.progressBar1.PerformStep(); } dir = ((Line1[il].x >> 14) & 2) | (Line1[il].y >> 15); x = Line1[il].x & 0X7FFF; y = Line1[il].y & 0X7FFF; if (nBits == 24) { switch (dir) { case 0: if (y > 0) { for (c = 0; c < nComp; c++) { Image.Grid[nComp * (x + width * y) + 2 - c] = (byte)((Palette[Line1[il].Ind1] >> 8 * c) & 0XFF); int ind = Line1[il].Ind0; byte col = (byte)((Palette[ind] >> 8 * c) & 0XFF); Image.Grid[nComp * (x + width * (y - 1)) + 2 - c] = col; //(byte)((Palette[Line1[il].Ind0]>>8*c) & 0XFF); } Mask.Grid[x + width * y] = Mask.Grid[x + width * (y - 1)] = (byte)LabMask; } break; case 1: for (c = 0; c < nComp; c++) { Image.Grid[nComp * (x + width * y) + 2 - c] = (byte)((Palette[Line1[il].Ind0] >> 8 * c) & 0XFF); Image.Grid[nComp * (x - 1 + width * y) + 2 - c] = (byte)((Palette[Line1[il].Ind1] >> 8 * c) & 0XFF); } Mask.Grid[x + width * y] = Mask.Grid[x - 1 + width * y] = (byte)LabMask; break; case 2: for (c = 0; c < nComp; c++) { Image.Grid[nComp * (x - 1 + width * y) + 2 - c] = (byte)((Palette[Line1[il].Ind0] >> 8 * c) & 0XFF); Image.Grid[nComp * (x - 1 + width * (y - 1)) + 2 - c] = (byte)((Palette[Line1[il].Ind1] >> 8 * c) & 0XFF); } Mask.Grid[x - 1 + width * y] = Mask.Grid[x - 1 + width * (y - 1)] = (byte)LabMask; break; case 3: for (c = 0; c < nComp; c++) { Image.Grid[nComp * (x + width * (y - 1)) + 2 - c] = (byte)((Palette[Line1[il].Ind1] >> 8 * c) & 0XFF); Image.Grid[nComp * (x - 1 + width * (y - 1)) + 2 - c] = (byte)((Palette[Line1[il].Ind0] >> 8 * c) & 0XFF); } Mask.Grid[x + width * (y - 1)] = Mask.Grid[x - 1 + width * (y - 1)] = (byte)LabMask; break; } } else { switch (dir) { case 0: Image.Grid[x + width * y] = Line1[il].Ind1; Image.Grid[x + width * (y - 1)] = Line1[il].Ind0; Mask.Grid[x + width * y] = Mask.Grid[x + width * (y - 1)] = (byte)LabMask; break; case 1: Image.Grid[x + width * y] = Line1[il].Ind0; Image.Grid[x - 1 + width * y] = Line1[il].Ind1; Mask.Grid[x + width * y] = Mask.Grid[x - 1 + width * y] = (byte)LabMask; break; case 2: Image.Grid[x - 1 + width * y] = Line1[il].Ind0; Image.Grid[x - 1 + width * (y - 1)] = Line1[il].Ind1; Mask.Grid[x - 1 + width * y] = Mask.Grid[x - 1 + width * (y - 1)] = (byte)LabMask; break; case 3: Image.Grid[x + width * (y - 1)] = Line1[il].Ind1; Image.Grid[x - 1 + width * (y - 1)] = Line1[il].Ind0; Mask.Grid[x + width * (y - 1)] = Mask.Grid[x - 1 + width * (y - 1)] = (byte)LabMask; break; } } } //================= end for (il... nLine1 ... ========================================== int cnt = 0, first, last; int[] Shift = { 0, 2, 4, 6 }; // Interpolation along the sides of long lines. // Long lines: if (nLine2 > 300) { jump = nLine2 / 20; } else { jump = 2; } for (il = 0; il < nLine2; il++) //============================================================ { if ((il % jump) == jump - 1) { fm1.progressBar1.PerformStep(); } if (il == 0) { first = 0; } else { first = Line[il - 1].EndByte + 1; } last = Line[il].EndByte; x = Line[il].x; y = Line[il].y; int iByte = first, iShift = 0; iVect2 V0 = new iVect2(0, 0); iVect2 P = V0, P1, PixelP = V0, PixelN = V0; // comb. coordinates byte[] ColN = new byte[3], ColP = new byte[3], ColStartN = new byte[3], ColStartP = new byte[3], ColLastN = new byte[3], ColLastP = new byte[3]; for (c = 0; c < 3; c++) { ColN[c] = ColP[c] = ColStartN[c] = ColStartP[c] = ColLastN[c] = ColLastP[c] = 0; } if (nBits == 24) { for (c = 0; c < nComp; c++) { ColStartN[2 - c] = (byte)((Palette[Line[il].Ind0] >> 8 * c) & 255); ColStartP[2 - c] = (byte)((Palette[Line[il].Ind1] >> 8 * c) & 255); ColLastN[2 - c] = (byte)((Palette[Line[il].Ind2] >> 8 * c) & 255); ColLastP[2 - c] = (byte)((Palette[Line[il].Ind3] >> 8 * c) & 255); } } else { ColStartN[0] = Line[il].Ind0; ColStartP[0] = Line[il].Ind1; ColLastN[0] = Line[il].Ind2; ColLastP[0] = Line[il].Ind3; } P.X = Line[il].x; P.Y = Line[il].y; int nCrack = Line[il].nCrack; int iC, xx, yy; // Interpolation along a line: for (iC = 0; iC < nCrack; iC++) //======================================================= { dir = (Byte[iByte] & (3 << Shift[iShift])) >> Shift[iShift]; switch (dir) // Standard coordinates { case 0: PixelP = P; PixelN = P + Step[3]; break; case 1: PixelP = P + Step[2]; PixelN = P; break; case 2: PixelP = P + Step[2] + Step[3]; PixelN = P + Step[2]; break; case 3: PixelP = P + Step[3]; PixelN = P + Step[2] + Step[3]; break; } for (c = 0; c < nComp; c++) //=================================================== { ColN[c] = (byte)((ColLastN[c] * iC + ColStartN[c] * (nCrack - iC - 1)) / (nCrack - 1)); // Interpolation ColP[c] = (byte)((ColLastP[c] * iC + ColStartP[c] * (nCrack - iC - 1)) / (nCrack - 1)); } //========================== end for (c... ================================ // Assigning colors to intermediate pixels of a line: xx = PixelP.X; yy = PixelP.Y; if (xx + width * yy < width * height && xx + width * yy >= 0) { for (c = 0; c < nComp; c++) { Image.Grid[c + nComp * xx + nComp * width * yy] = ColP[c]; // Assertion } Mask.Grid[xx + width * yy] = (byte)LabMask; } xx = PixelN.X; yy = PixelN.Y; if (xx + width * yy < width * height && xx + width * yy >= 0) { for (c = 0; c < nComp; c++) { Image.Grid[c + nComp * xx + nComp * width * yy] = ColN[c]; } Mask.Grid[xx + width * yy] = (byte)LabMask; } P1 = P; P = P + Step[dir]; iShift++; if (iShift == 4) { iShift = 0; iByte++; } } //=============================== end for (iC... ============================== int nZero = 0; if (P.X > 0 && P.Y > 0 && P.X < width && P.Y < height) { if (Image.Grid[nComp * (P.X + width * P.Y) + 0] == 0) { nZero++; } if (Image.Grid[nComp * (P.X - 1 + width * P.Y) + 0] == 0) { nZero++; } if (Image.Grid[nComp * (P.X - 1 + width * (P.Y - 1)) + 0] == 0) { nZero++; } if (Image.Grid[nComp * (P.X + width * (P.Y - 1)) + 0] == 0) { nZero++; } if (nZero == 2) { cnt++; } } } //================================= end for (il... nLine2 ... =========================== Mask.Grid[0] = Mask.Grid[width - 1] = Mask.Grid[width * height - 1] = Mask.Grid[width * (height - 1)] = (byte)LabMask; //fm1.progressBar1.Visible = false; return(1); } //*********************** end Restore **********************************************************
} //***************************************** end TraceLin *********************************************** public int ComponLin(byte[] CGrid, int X, int Y) /* Encodes in "CListLines" the lines 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 with the point 'P' fetched from the queue. * If the next point of the crack is a branch or an end point, then a short line is saved. * Otherwise the funktion "TraceLin" is called. "TraceLin" traces a long line, saves the color * indices at the sides of the line and ends at the point 'Pterm' with the direction 'DirT'. * Then the method "FreqInds" assigns the most frequent from the saved color indices to the line. * If the point 'Pterm' is a branch point then it is put to the queue. * "ComponLin" returns when the queue is empty. ---------------*/ { int dir, dirT; int LabNext, Mask = 7, rv; iVect2 Crack, P, Pinp, PixelN, PixelP, Pnext, Pterm = new iVect2(0, 0); Pinp = new iVect2(X, Y); // comb. coord. pQ.Put(Pinp); while (pQ.Empty() == false) //=========================================================================== { P = pQ.Get(); for (dir = 0; dir < 4; dir++) //================================================================ { Crack = P + Step[dir]; if (Crack.X < 0 || Crack.X > CNX - 1 || Crack.Y < 0 || Crack.Y > CNY - 1) { continue; } if (CGrid[Crack.X + CNX * Crack.Y] == 1) //---- ------------ ----------- { PixelP = Crack + Norm[dir]; PixelN = Crack - Norm[dir]; Pnext = Crack + Step[dir]; LabNext = CGrid[Pnext.X + CNX * Pnext.Y] & Mask; //Ind0 if (LabNext == 1 || LabNext == 3 || LabNext == 4) { Line1[nLine1].x = (ushort)(P.X / 2); Line1[nLine1].y = (ushort)(P.Y / 2); Line1[nLine1].Ind0 = CGrid[PixelN.X + CNX * PixelN.Y]; // correct: Ind0=PixelN Line1[nLine1].Ind1 = CGrid[PixelP.X + CNX * PixelP.Y]; if (nLine1 > MaxLine1 - 2) { MessageBox.Show("ComponLin: Overflow in Line1; return -1"); return(-1); } else { nLine1++; } } if (LabNext == 3 || LabNext == 4) { pQ.Put(Pnext); } if (LabNext == 2) //------------------------------------------------------------------------- { Line[nLine2].x = (ushort)(P.X / 2); Line[nLine2].y = (ushort)(P.Y / 2); // transformed to standard coord. dirT = dir; rv = TraceLin(CGrid, P.X, P.Y, ref Pterm, ref dirT); // NXP, if (nBits3 == 24) { FreqInds(nLine2); } else { AverageGray(nLine2); } if (rv < 0) { return(-1); } if (nLine2 > MaxLine2 - 2) { MessageBox.Show("ComponLin: Overflow in Line; return -1"); return(-1); } else { nLine2++; } if ((CGrid[Pterm.X + CNX * Pterm.Y] & 64) == 0) // '64' is a label for visited points; Pterm is new { if (rv == 3) //------------------------------------------------------ { CGrid[Pterm.X + CNX * Pterm.Y] |= 64; pQ.Put(Pterm); } } //------------ end if ((CGrid[Pterm.X... ---------------------------------------- } // ------------- end if (LabNest==2) ----------------------------------------------------- if ((CGrid[P.X + CNX * P.Y] & Mask) == 1) { break; } } //--------------- end if (CGrid[Crack.X ...==1) ------------------------------------------ } //================================== end for (dir ... ========================================== CGrid[P.X + CNX * P.Y] = 0; } //==================================== end while ================================================== return(1); } //************************************** end ComponLin ************************************************
} //****************************** end SearchLin ******************************** public int TraceLin(byte[] CGrid, int X, int Y, ref iVect2 Pterm, ref int dir) /* This method traces a line in the image "Image" with combinatorial coordinates, where the cracks * and points of the edges are labeled: bits 0, 1 and 2 of a point contain the label 1 to 4 of the point. * The label indicates the number of incident edge cracks. 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 method traces the edge from one end or branch point to another while changing the parameter "dir". * ----------*/ { bool atSt_P = false, BP = false, END = false; int rv = 0; iVect2 Crack, P = new iVect2(0, 0), PixelP, PixelN, StartPO; int iShift = -1, iCrack = 0, Lab, Mask = 7; P.X = X; P.Y = Y; StartPO = P; if (nLine2 == 0) { nByte = 0; } else { nByte = Line[nLine2 - 1].EndByte + 1; } int[] Shift = { 0, 2, 4, 6 }; while (true) //==================================================================== { Crack = P + Step[dir]; if (Crack.Y == -1 && dir == 3) { Pterm = P; break; } P = Crack + Step[dir]; Lab = CGrid[P.X + CNX * P.Y] & Mask; 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 = 3; break; } PixelP = Crack + Norm[dir]; PixelN = Crack - Norm[dir]; IndPos[iCrack] = CGrid[PixelP.X + CNX * PixelP.Y]; IndNeg[iCrack] = CGrid[PixelN.X + CNX * PixelN.Y]; if (Lab == 2) { CGrid[P.X + CNX * P.Y] = 0; } iShift++; iCrack++; if (iShift == 4) { iShift = 0; if (nByte < MaxByte - 1) { nByte++; } else { return(-1); } } Byte[nByte] |= (byte)(dir << Shift[iShift]); if (P.X == StartPO.X && P.Y == StartPO.Y) { atSt_P = true; } else { atSt_P = false; } if (atSt_P) { Pterm = P; rv = 2; break; } if (!BP && !END) //--------------------------- { Crack = P + Step[(dir + 1) % 4]; if (CGrid[Crack.X + CNX * Crack.Y] == 1) { dir = (dir + 1) % 4; } else { Crack = P + Step[(dir + 3) % 4]; if (CGrid[Crack.X + CNX * Crack.Y] == 1) { dir = (dir + 3) % 4; } } } else { Pterm = P; break; } //----------------- end if (!BP && !END) -------------------- } //======================================= end while ============================================ Line[nLine2].EndByte = nByte; Line[nLine2].nCrack = (ushort)iCrack; return(rv); } //***************************************** end TraceLin ***********************************************