public static void ordenaAET() { if (aet != null) { ET ant = aet, prox = aet.prox, aux = new ET(); int j, tl = calculaTL_AET(); while (tl > 0) { prox = aet; j = 0; while (j < tl - 1) { if (prox.xmin > prox.prox.xmin) { aux.ymax = prox.ymax; aux.xmin = prox.xmin; aux.incx = prox.incx; prox.ymax = prox.prox.ymax; prox.xmin = prox.prox.xmin; prox.incx = prox.prox.incx; prox.prox.ymax = aux.ymax; prox.prox.xmin = aux.xmin; prox.prox.incx = aux.incx; } prox = prox.prox; j++; } tl--; } } }
private static void excluiAET(int y) { ET ant = aet, aux = aet; while (aux != null) { if (aux.ymax == y) { if (aux == aet) { aet = aet.prox; ant = aux = aet; } else { ant.prox = aux.prox; aux = aux.prox; } } else { ant = aux; aux = aux.prox; } } }
private static void criaET(Poligono p) { ET caixa; et = new ET[buscaMaxY(p)]; for (int i = 0; i < p.linha - 2; i++) { caixa = new ET(); caixa.xmin = p.MAXY[i, 0]; caixa.ymax = p.MAXY[i + 1, 1]; try { caixa.incx = (p.MAXY[i + 1, 0] - p.MAXY[i, 0]) / (p.MAXY[i + 1, 1] - p.MAXY[i, 1]); } catch (Exception ex) { caixa.incx = 0; } caixa.prox = et[p.MAXY[i, 1]]; et[p.MAXY[i, 1]] = caixa; } caixa = new ET(); caixa.xmin = p.MAXY[p.linha - 1, 0]; caixa.ymax = p.MAXY[0, 1]; caixa.incx = (p.MAXY[0, 0] - p.MAXY[p.linha - 1, 0]) / (p.MAXY[0, 1] - p.MAXY[p.linha - 1, 1]); caixa.prox = et[p.MAXY[p.linha - 1, 1] - 1]; et[p.MAXY[p.linha - 1, 1]] = caixa; }
private static void atualizaXmin() { ET aux = aet; while (aux != null) { aux.xmin += aux.incx; aux = aux.prox; } }
private static int calculaTL_AET() { ET aux = aet; int tl = 0; while (aux != null) { tl++; aux = aux.prox; } return(tl); }
private static void desenhaLinha(int cx, int cy, int y, int r, int g, int b, Bitmap imageBitmapSrc) { if (aet != null) { int width = imageBitmapSrc.Width; int height = imageBitmapSrc.Height; int x = (int)Math.Floor(aet.xmin); ET caixa1 = aet, caixa2 = aet.prox; bool flag = true; //lock dados bitmap origem BitmapData bitmapDataSrc = imageBitmapSrc.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int padding = bitmapDataSrc.Stride - (width * 3); unsafe { byte *src = (byte *)bitmapDataSrc.Scan0.ToPointer(); src += (int)((cy + y) * (width * 3 + padding) + (cx + x) * 3); *(src++) = (byte)b; *(src++) = (byte)g; *(src++) = (byte)r; while (flag) { for (x = (int)Math.Floor(caixa1.xmin); x < Math.Ceiling(caixa2.xmin); x++) { src = (byte *)bitmapDataSrc.Scan0.ToPointer(); src += (int)((cy + y) * (width * 3 + padding) + (cx + x) * 3); *(src++) = (byte)b; *(src++) = (byte)g; *(src++) = (byte)r; } if (caixa2.prox != null) { caixa1 = caixa2.prox; caixa2 = caixa1.prox; } else { flag = false; } } } //unlock imagem origem imageBitmapSrc.UnlockBits(bitmapDataSrc); } }
public static void Scanline(Poligono p, int cx, int cy, int r, int g, int b, Bitmap imageBitmapSrc) { int y; criaET(p); aet = null; for (y = 0; et[y] != null; y++) { } //aet = et[y]; do { insereAET(y); excluiAET(y); ordenaAET(); desenhaLinha(cx, cy, y, r, g, b, imageBitmapSrc); atualizaXmin(); y++; }while (aet != null); }
private static void insereAET(int y) { ET aux, caixa, auxET = et[y], ant, ini; if (auxET != null) { caixa = new ET(); caixa.ymax = auxET.ymax; caixa.xmin = auxET.xmin; caixa.incx = auxET.incx; ini = ant = caixa; auxET = auxET.prox; while (auxET != null) { caixa = new ET(); caixa.ymax = auxET.ymax; caixa.xmin = auxET.xmin; caixa.incx = auxET.incx; ant.prox = caixa; auxET = auxET.prox; } if (aet == null) { aet = ini; } else { aux = aet; while (aux.prox != null) { aux = aux.prox; } aux.prox = ini; } } }
public ET() { ymax = xmin = incx = 0.0; prox = null; }