public static void rawTriangleWithZBuffer(Polygon polygon, Image2D image2D, ColorRGB colorRgb, ZBuffer zBuffer) { int xMin = Math.Min(Math.Min(polygon[0].X, polygon[1].X), polygon[2].X) < 0 ? 0 : Math.Min(Math.Min(polygon[0].X, polygon[1].X), polygon[2].X); int xMax = Math.Max(Math.Max(polygon[0].X, polygon[1].X), polygon[2].X) > image2D.Width ? image2D.Width : Math.Max(Math.Max(polygon[0].X, polygon[1].X), polygon[2].X); int yMin = Math.Min(Math.Min(polygon[0].Y, polygon[1].Y), polygon[2].Y) < 0 ? 0 : Math.Min(Math.Min(polygon[0].Y, polygon[1].Y), polygon[2].Y); int yMax = Math.Max(Math.Max(polygon[0].Y, polygon[1].Y), polygon[2].Y) > image2D.Height ? image2D.Height : Math.Max(Math.Max(polygon[0].Y, polygon[1].Y), polygon[2].Y); BarycentricPoint barycentricPoint = new BarycentricPoint(polygon); for (int x = xMin; x < xMax; x++) { for (int y = yMin; y < yMax; y++) { barycentricPoint.calculateLambds(new Point3D(x, y)); if (barycentricPoint.Lambda0 >= 0 && barycentricPoint.Lambda1 >= 0 && barycentricPoint.Lambda2 >= 0) { double z = barycentricPoint.Lambda0 * polygon[0].Z + barycentricPoint.Lambda1 * polygon[1].Z + barycentricPoint.Lambda2 * polygon[2].Z; if (z < zBuffer.getZBuffer(x, y)) { zBuffer.setZBuffer(x, y, z); image2D.setPixel(x, y, colorRgb); } } } } }
private void button7_Click(object sender, EventArgs e) { TestObj testObj = new TestObj(false); List <string> file = new List <string>(); using (StreamReader sr = new StreamReader(@"Test.obj", System.Text.Encoding.Default)) { string str; while ((str = sr.ReadLine()) != null) { file.Add(str); } } Regex floatNumber = new Regex(@"(?:-)?0[.]\d*"); Regex intNumber = new Regex(@"\d+"); foreach (string temp in file) { if (temp[0] == 'v' && temp[1] == ' ') { MatchCollection matchCollection = floatNumber.Matches(temp); double x = Convert.ToDouble(matchCollection[0].Value.Replace('.', ',')); double y = Convert.ToDouble(matchCollection[1].Value.Replace('.', ',')); double z = Convert.ToDouble(matchCollection[2].Value.Replace('.', ',')); Point3D point = new Point3D(x, y, z, 4000, 500); testObj.points.Add(point); } } foreach (string temp in file) { if (temp[0] == 'f') { MatchCollection matchCollection = intNumber.Matches(temp); int p1 = Convert.ToInt32(matchCollection[0].Value); int p2 = Convert.ToInt32(matchCollection[3].Value); int p3 = Convert.ToInt32(matchCollection[6].Value); Polygon polygon = new Polygon(); polygon[0] = testObj.points[p1 - 1]; polygon[1] = testObj.points[p2 - 1]; polygon[2] = testObj.points[p3 - 1]; testObj.polygons.Add(polygon); // далее пойдет просто проверка на расчет бприцентрических координат точки относительно вершин треуголника // здесь это удобнее так как тут идет создание всех полигонов модели BarycentricPoint barycentricPoint = new BarycentricPoint(polygon); barycentricPoint.calculateLambds(polygon[0]); if (Math.Abs(1 - barycentricPoint.Lambda0 - barycentricPoint.Lambda1 - barycentricPoint.Lambda2) > 0.001) { MessageBox.Show("Сумма барицентрических координат не равна 1!!!", "Ошибка", MessageBoxButtons.OK); } } } testObj.Show(); }
public static void rawTriangleWithGuruAndZBuffer(Polygon polygon, Image2D image2D, ZBuffer zBuffer) { int xMin = Math.Min(Math.Min(polygon[0].X, polygon[1].X), polygon[2].X) < 0 ? 0 : Math.Min(Math.Min(polygon[0].X, polygon[1].X), polygon[2].X); int xMax = Math.Max(Math.Max(polygon[0].X, polygon[1].X), polygon[2].X) > image2D.Width ? image2D.Width : Math.Max(Math.Max(polygon[0].X, polygon[1].X), polygon[2].X); int yMin = Math.Min(Math.Min(polygon[0].Y, polygon[1].Y), polygon[2].Y) < 0 ? 0 : Math.Min(Math.Min(polygon[0].Y, polygon[1].Y), polygon[2].Y); int yMax = Math.Max(Math.Max(polygon[0].Y, polygon[1].Y), polygon[2].Y) > image2D.Height ? image2D.Height : Math.Max(Math.Max(polygon[0].Y, polygon[1].Y), polygon[2].Y); BarycentricPoint barycentricPoint = new BarycentricPoint(polygon); double l0 = MatrixUtil.cosDirectionEarthNormal(polygon.Norms[0]); double l1 = MatrixUtil.cosDirectionEarthNormal(polygon.Norms[1]); double l2 = MatrixUtil.cosDirectionEarthNormal(polygon.Norms[2]); for (int x = xMin; x < xMax; x++) { for (int y = yMin; y < yMax; y++) { barycentricPoint.calculateLambds(new Point3D(x, y)); if (barycentricPoint.Lambda0 >= 0 && barycentricPoint.Lambda1 >= 0 && barycentricPoint.Lambda2 >= 0) { double z = barycentricPoint.Lambda0 * polygon[0].Z + barycentricPoint.Lambda1 * polygon[1].Z + barycentricPoint.Lambda2 * polygon[2].Z; if (z < zBuffer.getZBuffer(x, y)) { int brightness = (int)Math.Abs((255 * (barycentricPoint.Lambda0 * l0 + barycentricPoint.Lambda1 * l1 + barycentricPoint.Lambda2 * l2))); zBuffer.setZBuffer(x, y, z); image2D.setPixel(x, y, new ColorRGB(brightness, brightness, brightness)); } } } } }