private bool GetPolygen(My3DPolygon PG) { int d; int i = 0; do { d = (int)((PG.Points[i].X - PG.Points[i + 2].X) * (PG.Points[i].Y - PG.Points[i + 1].Y) - (PG.Points[i].X - PG.Points[i + 1].X) * (PG.Points[i].Y - PG.Points[i + 2].Y)); i++; } while (d == 0 || i + 2 < PG.number); if (d != 0) { i--; A = ((PG.Points[i].Z - PG.Points[i + 2].Z) * (PG.Points[i].Y - PG.Points[i + 1].Y) - (PG.Points[i].Z - PG.Points[i + 1].Z) * (PG.Points[i].Y - PG.Points[i + 2].Y)) / d; B = ((PG.Points[i].Z - PG.Points[i + 1].Z) * (PG.Points[i].X - PG.Points[i + 2].X) - (PG.Points[i].Z - PG.Points[i + 2].Z) * (PG.Points[i].X - PG.Points[i + 1].X)) / d; C = PG.Points[i].Z - A * PG.Points[i].X - B * PG.Points[i].Y; return(true); } else { return(false); } }
private void ZBufferPolygon(My3DPolygon PG, double[,] Z) { if (!GetPolygen(PG)) { return; } Point[] g1 = new Point[100]; EdgeInfo[] edgelist = new EdgeInfo[100]; int j = 0, yu = 0, yd = 1024; for (int i = 0; i < PG.number; i++) { g1[i].X = (int)(PG.Points[i].X + 0.5); g1[i].Y = (int)(PG.Points[i].Y + 0.5); } g1[PG.number].X = (int)(PG.Points[0].X + 0.5); g1[PG.number].Y = (int)(PG.Points[0].Y + 0.5); for (int i = 0; i < PG.number; i++) { if (g1[i].Y > yu) { yu = g1[i].Y; } if (g1[i].Y < yd) { yd = g1[i].Y; } if (g1[i].Y != g1[i + 1].Y) { if (g1[i].Y > g1[i + 1].Y) { edgelist[j++] = new EdgeInfo(g1[i + 1].X, g1[i + 1].Y, g1[i].X, g1[i].Y); } else { edgelist[j++] = new EdgeInfo(g1[i].X, g1[i].Y, g1[i + 1].X, g1[i + 1].Y); } } } Graphics g = CreateGraphics(); for (int y = yd; y < yu; y++) { var sorted = from item in edgelist where y < item.YMax && y >= item.YMin orderby item.XMin, item.K select item; int flag = 0; foreach (var item in sorted) { if (flag == 0) { FirstX = (int)(item.XMin + 0.5); flag++; } else { Pen p = new Pen(PG.pcolor); for (int x = FirstX; x < (int)(item.XMin + 0.5); x++) { double z = A * x + B * y + C; if (z > Z[x, y]) { Z[x, y] = z; g.DrawRectangle(p, x, y, 1, 1); } } flag = 0; } } for (int i = 0; i < j; i++) { if (y < edgelist[i].YMax - 1 && y > edgelist[i].YMin) { edgelist[i].XMin += edgelist[i].K; } } } }