// создание треугольников public static void createTriangle(clsPolygon polygon, cls2D_Picture image, clsRGB colour) { minimalX = functionMinimumX(polygon); maximalX = functionMaximumX(polygon, image); minimalY = functionMinimumY(polygon); maximalY = functionMaximumY(polygon, image); clsBarycentricCoordinates barycentricPoint = new clsBarycentricCoordinates(polygon); for (int x = minimalX; x < maximalX; x++) { for (int y = minimalY; y < maximalY; y++) { barycentricPoint.Calculating_lambda_coefficients(new cls3D_Point(x, y)); if (barycentricPoint.Lambda0 >= 0 && barycentricPoint.Lambda1 >= 0 && barycentricPoint.Lambda2 >= 0) { image.setPixel(x, y, colour); } } } }
// преобразование цвета public static Color ColorRGBtoColor(clsRGB value) { Color color = Color.FromArgb(value.Red, value.Green, value.Blue); return(color); }
// метод доступа к пикселям // постановка по координантам цветового пикселя public void setPixel(int x, int y, clsRGB rgbColour) { colorsList[x + Width * y] = rgbColour; }
// алгоритм Брезенхема public static void line4(int x0, int y0, int x1, int y1, cls2D_Picture image, clsRGB color) { bool steep = false; if (Math.Abs(x0 - x1) < Math.Abs(y0 - y1)) { swap(ref x0, ref y0); swap(ref x1, ref y1); steep = true; } if (x0 > x1) { swap(ref x0, ref x1); swap(ref y0, ref y1); } int dx = x1 - x0; int dy = y1 - y0; float derror = Math.Abs(dy / (float)dx); float error = 0; int y = y0; for (int x = x0; x <= x1; x++) { if (steep) { image.setPixel(y, x, color); } else { image.setPixel(x, y, color); } error += derror; if (error > 0.5) { y += (y1 > y0 ? 1 : -1); error -= 1.0F; } } }
// улучшенный первый алгоритм public static void line3(int x0, int y0, int x1, int y1, cls2D_Picture image, clsRGB color) { bool steep = false; if (Math.Abs(x0 - x1) < Math.Abs(y0 - y1)) { swap(ref x0, ref y0); swap(ref x1, ref y1); steep = true; } if (x0 > x1) { swap(ref x0, ref x1); swap(ref y0, ref y1); } for (int x = x0; x <= x1; x++) { float t = (x - x0) / (float)(x1 - x0); int y = Convert.ToInt32(y0 * (1 - t) + y1 * t); if (steep) { image.setPixel(y, x, color); } else { image.setPixel(x, y, color); } } }
// модифицированный вариант public static void line2(int x0, int y0, int x1, int y1, cls2D_Picture image, clsRGB color) { for (int x = x0; x <= x1; x++) { float t = (x - x0) / (float)(x1 - x0); int y = Convert.ToInt32(y0 * (1 - t) + y1 * t); image.setPixel(x, y, color); } }
// простейший алгоритм отрисовки линии public static void line1(int x0, int y0, int x1, int y1, cls2D_Picture image, clsRGB color) { for (float t = 0.0F; t < 1.0F; t += 0.01F) { int x = Convert.ToInt32(x0 * (1 - t) + x1 * t); int y = Convert.ToInt32(y0 * (1 - t) + y1 * t); image.setPixel(x, y, color); } }
// создание треугольниов с помощью z буфера public static void createTriangleWithZBuffer(clsPolygon polygon, cls2D_Picture image, clsRGB colour, clsZbuffer zBuffer) { minimalX = functionMinimumX(polygon); maximalX = functionMaximumX(polygon, image); minimalY = functionMinimumY(polygon); maximalY = functionMaximumY(polygon, image); clsBarycentricCoordinates barycentricPoint = new clsBarycentricCoordinates(polygon); for (int x = minimalX; x < maximalX; x++) { for (int y = minimalY; y < maximalY; y++) { barycentricPoint.Calculating_lambda_coefficients(new cls3D_Point(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); image.setPixel(x, y, colour); } } } } }