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 List <clsPolygonModified> loadPolygonsFromObjectFileWithCheckForTransformation() { pointsForTransformation = loadTopsFromObjectFileForTransformation(); // считываем информацию for (int i = 0; i < lines.Length; i++) { words = lines[i].Split(' '); if (words[0] == "f") { words = lines[i].Split(' ', '/'); // считываем координаты полигонов polygon1 = int.Parse(words[1]); polygon2 = int.Parse(words[4]); polygon3 = int.Parse(words[7]); clsPolygonModified polygon = new clsPolygonModified(); // записываем полигон polygon[0] = pointsForTransformation[polygon1 - 1]; polygon[1] = pointsForTransformation[polygon2 - 1]; polygon[2] = pointsForTransformation[polygon3 - 1]; clsBarycentricCoordinates barycentricCoordinates = new clsBarycentricCoordinates(polygon); barycentricCoordinates.calc_lambda_for_Original(polygon[0]); if (Math.Abs(1 - barycentricCoordinates.Lambda0 - barycentricCoordinates.Lambda1 - barycentricCoordinates.Lambda2) > 0.001) { MessageBox.Show("Сумма барицентрических координат не равна 1!", "Ошибка", MessageBoxButtons.OK); } polygonsForTransformation.Add(polygon); // сохраняем в лист } } return(polygonsForTransformation); }
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 funcMinimumY(clsPolygonModified poligon) { minimalY = (int)Math.Min(Math.Min(poligon[0].projectiveY, poligon[1].projectiveY), poligon[2].projectiveY); if (minimalY < 0) { minimalY = 0; } return(minimalY); }
public static int funcMinimumX(clsPolygonModified poligon) { minimalX = (int)Math.Min(Math.Min(poligon[0].projectiveX, poligon[1].projectiveX), poligon[2].projectiveX); if (minimalX < 0) { minimalX = 0; } return(minimalX); }
public static double getCosNormal(clsPolygonModified polygon) { clsVector normaliseVector = getNormal(polygon); // скалярное произведение double scalarMulty = normaliseVector.X * vectorLight.X + normaliseVector.Y * vectorLight.Y + normaliseVector.Z * vectorLight.Z; // норма вектора double normalVectorLength = Math.Sqrt(normaliseVector.X * normaliseVector.X + normaliseVector.Y * normaliseVector.Y + normaliseVector.Z * normaliseVector.Z); return(scalarMulty / normalVectorLength); }
public static clsVector getNormal(clsPolygonModified polygon) { double x0 = polygon[0].movementX; double y0 = polygon[0].movementY; double z0 = polygon[0].movementZ; double x1 = polygon[1].movementX; double y1 = polygon[1].movementY; double z1 = polygon[1].movementZ; double x2 = polygon[2].movementX; double y2 = polygon[2].movementY; double z2 = polygon[2].movementZ; // нахождение координат нормали через определитель double x = (y1 - y0) * (z1 - z2) - (z1 - z0) * (y1 - y2); double y = (x1 - x2) * (z1 - z0) - (z1 - z2) * (x1 - x0); double z = (x1 - x0) * (y1 - y2) - (y1 - y0) * (x1 - x2); return(new clsVector(x, y, z)); }
public clsBarycentricCoordinates(clsPolygonModified polyg) { polygonModified = polyg; }
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); } } } } }