// создание треугольниов с помощью 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); } } } } }
// улучшенный первый алгоритм 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 int functionMaximumX(clsPolygon poligon, cls2D_Picture Picture) { maximalX = Math.Max(Math.Max(poligon[0].X, poligon[1].X), poligon[2].X); if (maximalX > Picture.width) { maximalX = Picture.width; } return(maximalX); }
// простейший алгоритм отрисовки линии 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); } }
// модифицированный вариант 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 int funcMaximumY(clsPolygonModified poligon, cls2D_Picture Picture) { maximalY = (int)Math.Max(Math.Max(poligon[0].projectiveY, poligon[1].projectiveY), poligon[2].projectiveY); if (maximalY > Picture.height) { maximalY = Picture.height; } return(maximalY); }
public static int funcMaximumX(clsPolygonModified poligon, cls2D_Picture Picture) { maximalX = (int)Math.Max(Math.Max(poligon[0].projectiveX, poligon[1].projectiveX), poligon[2].projectiveX); if (maximalX > Picture.width) { maximalX = Picture.width; } return(maximalX); }
public static int functionMaximumY(clsPolygon poligon, cls2D_Picture Picture) { maximalY = Math.Max(Math.Max(poligon[0].Y, poligon[1].Y), poligon[2].Y); if (maximalY > Picture.height) { maximalY = Picture.height; } return(maximalY); }
public static cls2D_Picture drawTopsFromObjectFile(List <cls3D_Point> points) { cls2D_Picture pointsImage = new cls2D_Picture(1800, 1500); // создаем фон изображения for (int i = 0; i < points.Count - 1; i++) { cls3D_Point temp = points[i]; pointsImage.setPixel(temp.X, temp.Y, new clsRGB(255, 0, 0)); // рисуем ранее записанные точки } return(pointsImage); }
// отрисовка треугольниками public static cls2D_Picture drawTriangle() { cls2D_Picture polygonsImage = new cls2D_Picture(1700, 1500); Random random = new Random(); for (int i = 0; i < clsLoadData.polygonsForLineTrans.Count - 1; i++) { createTriangle(clsLoadData.polygonsForLineTrans[i], polygonsImage, new clsRGB(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255))); } return(polygonsImage); }
public static cls2D_Picture drawLine(int j) // отрисовка линий { cls2D_Picture imageLines = new cls2D_Picture(200, 200); switch (j) // выбор алгоритма { case 1: { for (int i = 0; i < 13; i++) { double alpha = 2 * i * Math.PI / 13; clsAlgorithmDrawLine.line1(100, 100, Convert.ToInt32(100 + 95 * Math.Cos(alpha)), Convert.ToInt32(100 + 95 * Math.Sin(alpha)), imageLines, new clsRGB(255, 0, 0)); } }; break; case 2: { for (int i = 0; i < 13; i++) { double alpha = 2 * i * Math.PI / 13; clsAlgorithmDrawLine.line2(100, 100, Convert.ToInt32(100 + 95 * Math.Cos(alpha)), Convert.ToInt32(100 + 95 * Math.Sin(alpha)), imageLines, new clsRGB(255, 0, 0)); } }; break; case 3: { for (int i = 0; i < 13; i++) { double alpha = 2 * i * Math.PI / 13; clsAlgorithmDrawLine.line3(100, 100, Convert.ToInt32(100 + 95 * Math.Cos(alpha)), Convert.ToInt32(100 + 95 * Math.Sin(alpha)), imageLines, new clsRGB(255, 0, 0)); } }; break; case 4: { for (int i = 0; i < 13; i++) { double alpha = 2 * i * Math.PI / 13; clsAlgorithmDrawLine.line4(100, 100, Convert.ToInt32(100 + 95 * Math.Cos(alpha)), Convert.ToInt32(100 + 95 * Math.Sin(alpha)), imageLines, new clsRGB(255, 0, 0)); } }; break; } return(imageLines); // возврат изображения }
// преобразование картинки в формат Bitmap public static Bitmap picture2DtoBitmap(cls2D_Picture image2D) { Bitmap result = new Bitmap(image2D.Width, image2D.Height); for (int x = 0; x < image2D.Width; x++) { for (int y = 0; y < image2D.Height; y++) { result.SetPixel(x, y, ColorRGBtoColor(image2D.getColor(x, y))); } } return(result); }
public static cls2D_Picture drawPolygonsFromObjectFile(List <clsPolygon> polygons) { cls2D_Picture polygonsImage = new cls2D_Picture(1800, 1500); // фон for (int i = 0; i < polygons.Count - 1; i++) // рисуем полигон по алгоритму Брезенхема { clsPolygon poligonchik = polygons[i]; clsAlgorithmDrawLine.line4(poligonchik[0].X, poligonchik[0].Y, poligonchik[1].X, poligonchik[1].Y, polygonsImage, new clsRGB(0, 0, 255)); clsAlgorithmDrawLine.line4(poligonchik[0].X, poligonchik[0].Y, poligonchik[2].X, poligonchik[2].Y, polygonsImage, new clsRGB(0, 0, 255)); clsAlgorithmDrawLine.line4(poligonchik[1].X, poligonchik[1].Y, poligonchik[2].X, poligonchik[2].Y, polygonsImage, new clsRGB(0, 0, 255)); } return(polygonsImage); }
// отрисовка треуголниками с помощью z буфера объемного изображения public static cls2D_Picture drawTriangleWithZBuffer() { cls2D_Picture polygonsImage = new cls2D_Picture(1700, 1500); clsZbuffer zBuffer = new clsZbuffer(1700, 1500); for (int i = 0; i < clsLoadData.polygonsForLineTrans.Count - 1; i++) { createTriangleWithZBuffer(clsLoadData.polygonsForLineTrans[i], polygonsImage, new clsRGB((int)Math.Abs(clsVectorsOperations.cosDirectionEarthNormal(clsLoadData.polygonsForLineTrans[i]) * 128), (int)Math.Abs(clsVectorsOperations.cosDirectionEarthNormal(clsLoadData.polygonsForLineTrans[i]) * 128), 0), zBuffer); } return(polygonsImage); }
// отрисовка красного квадрата public static cls2D_Picture createRedImage() { cls2D_Picture redImage = new cls2D_Picture(widht, height); for (int i = 0; i < widht; i++) { for (int j = 0; j < height; j++) { redImage.setPixel(i, j, new clsRGB(255, 0, 0)); } } return(redImage); }
public static cls2D_Picture drawTriangleWithZBufferForTransformationWithModifiedLight() { cls2D_Picture polygonsImage = new cls2D_Picture(5000, 5000); clsZbuffer zBuffer = new clsZbuffer(5000, 5000); for (int i = 0; i < clsLoadData.polygonsForTransformation.Count; i++) { if (clsVectorsOperations.getCosNormal(clsLoadData.polygonsForTransformation[i]) < 0) { createTriangleWithZBufferForTransformationWithModifiedLight(clsLoadData.polygonsForTransformation[i], clsLoadData.normPolygons[i], polygonsImage, zBuffer, i); } else { continue; } } return(polygonsImage); }
// отрисовка треугольниками объемного изображения public static cls2D_Picture drawVolTriangle() { cls2D_Picture polygonsImage = new cls2D_Picture(1700, 1500); Random random = new Random(); for (int i = 0; i < clsLoadData.polygonsForLineTrans.Count - 1; i++) { if (clsVectorsOperations.cosDirectionEarthNormal(clsLoadData.polygonsForLineTrans[i]) < 0) { createTriangle(clsLoadData.polygonsForLineTrans[i], polygonsImage, new clsRGB((int)Math.Abs(clsVectorsOperations.cosDirectionEarthNormal(clsLoadData.polygonsForLineTrans[i]) * 255), 0, 0)); } else { continue; } } return(polygonsImage); }
// создание треугольников 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 cls2D_Picture createGradImage() { cls2D_Picture gradImage = new cls2D_Picture(widht, height); // задаем размерность картинки int[,] grad = new int[widht, height]; for (int i = 0; i < widht; i++) { for (int j = 0; j < height; j++) { grad[i, j] = (i + j) % 256; // задаем массив цветовых пикселей } } for (int i = 0; i < widht; i++) { for (int j = 0; j < height; j++) { gradImage.setPixel(i, j, new clsRGB(grad[i, j], grad[i, j], grad[i, j])); // отрисовка полученного массива } } return(gradImage); }
// отрисовка белого квадрата public static cls2D_Picture createWhiteImage() { cls2D_Picture whiteImage = new cls2D_Picture(widht, height); // задаем размерность картинки int[,] white = new int[widht, height]; for (int i = 0; i < widht; i++) { for (int j = 0; j < height; j++) { white[i, j] = 255; // залдаем массив белых пискелей } } for (int i = 0; i < widht; i++) { for (int j = 0; j < height; j++) { whiteImage.setPixel(i, j, new clsRGB(white[i, j], white[i, j], white[i, j])); // рисуем массив } } return(whiteImage); // возвращаем полученное изображдение }
// отрисовка черного квадрата public static cls2D_Picture createBlackImage() { cls2D_Picture blackImage = new cls2D_Picture(widht, height); // задаем размерность картинки int[,] black = new int[widht, height]; for (int i = 0; i < widht; i++) { for (int j = 0; j < height; j++) { black[i, j] = 0; // задаем массив черных пикселей } } for (int i = 0; i < widht; i++) { for (int j = 0; j < height; j++) { blackImage.setPixel(i, j, new clsRGB(black[i, j], black[i, j], black[i, j])); // рисуем массив } } return(blackImage); // возврат изображения }
// алгоритм Брезенхема 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 createTriangleWithZBufferForTransformation(clsPolygonModified polygon, cls2D_Picture image, clsZbuffer zBuffer, int i) { minimalX = funcMinimumX(polygon); maximalX = funcMaximumX(polygon, image); minimalY = funcMinimumY(polygon); maximalY = funcMaximumY(polygon, image); clsBarycentricCoordinates barycentricPoint = new clsBarycentricCoordinates(polygon); for (int x = minimalX; x <= maximalX; x++) { for (int y = minimalY; y <= maximalY; y++) { barycentricPoint.calc_lambda_for_Transformation(x, y); if (barycentricPoint.lambda0 > 0 && barycentricPoint.lambda1 > 0 && barycentricPoint.lambda2 > 0) { double z = barycentricPoint.lambda0 * polygon[0].originalZ + barycentricPoint.lambda1 * polygon[1].originalZ + barycentricPoint.lambda2 * polygon[2].originalZ; if (z < zBuffer.getZBuffer(x, y)) { zBuffer.setZBuffer(x, y, z); image.setPixel(x, y, new clsRGB((int)Math.Abs(clsVectorsOperations.getCosNormal(clsLoadData.polygonsForTransformation[i]) * 255), 0, 0)); } } } } }
public static void createTriangleWithZBufferForTransformationWithModifiedLight(clsPolygonModified polygon, clsNormsPolygon normsPolygon, cls2D_Picture image, clsZbuffer zBuffer, int i) { minimalX = funcMinimumX(polygon); maximalX = funcMaximumX(polygon, image); minimalY = funcMinimumY(polygon); maximalY = funcMaximumY(polygon, image); clsBarycentricCoordinates barycentricPoint = new clsBarycentricCoordinates(polygon); double l0 = clsVectorsOperations.scalarMulty(normsPolygon[0]) / (clsVectorsOperations.lengthNorm(normsPolygon[0]) * clsVectorsOperations.lengthVectorLight()); double l1 = clsVectorsOperations.scalarMulty(normsPolygon[1]) / (clsVectorsOperations.lengthNorm(normsPolygon[1]) * clsVectorsOperations.lengthVectorLight()); double l2 = clsVectorsOperations.scalarMulty(normsPolygon[2]) / (clsVectorsOperations.lengthNorm(normsPolygon[2]) * clsVectorsOperations.lengthVectorLight()); for (int x = minimalX; x <= maximalX; x++) { for (int y = minimalY; y <= maximalY; y++) { barycentricPoint.calc_lambda_for_Transformation(x, y); if (barycentricPoint.lambda0 > 0 && barycentricPoint.lambda1 > 0 && barycentricPoint.lambda2 > 0) { double z = barycentricPoint.lambda0 * polygon[0].originalZ + barycentricPoint.lambda1 * polygon[1].originalZ + barycentricPoint.lambda2 * polygon[2].originalZ; if (z < zBuffer.getZBuffer(x, y)) { int brightness = (int)Math.Abs((255 * (barycentricPoint.lambda0 * l0 + barycentricPoint.lambda1 * l1 + barycentricPoint.lambda2 * l2))); image.setPixel(x, y, new clsRGB(brightness, 0, 0)); zBuffer.setZBuffer(x, y, z); } } } } }