public static VectorMethods CrossProduct(VectorMethods v1, VectorMethods v2) { VectorMethods vec = new VectorMethods(); vec.x = v1.y * v2.z - v1.z * v2.y; vec.y = v1.z * v2.x - v1.x * v2.z; vec.z = v1.x * v2.y - v1.y * v2.x; return(vec); }
public static VectorMethods SubVectors(VectorMethods v1, VectorMethods v2) { VectorMethods vec = new VectorMethods { x = v1.x - v2.x, y = v1.y - v2.y, z = v1.z - v2.z }; return(vec); }
public static VectorMethods MultiplyByNumber(VectorMethods v, float a) { VectorMethods vec = new VectorMethods { x = v.x * a, y = v.y * a, z = v.z * a }; return(vec); }
public static VectorMethods AddVectors(VectorMethods v1, VectorMethods v2) { VectorMethods vec = new VectorMethods { x = v1.x + v2.x, y = v1.y + v2.y, z = v1.z + v2.z }; return(vec); }
public static VectorMethods DivideByNumber(VectorMethods v, float a) { VectorMethods vec = new VectorMethods { x = v.x / a, y = v.y / a, z = v.z / a }; return(vec); }
public static VectorMethods VectorNormalise(VectorMethods v) { float length = LengthOfVector(v); VectorMethods normal = new VectorMethods { x = v.x / length, y = v.y / length, z = v.z / length }; return(normal); }
public GetMesh(string fileName) { List <VectorMethods> vectors = new List <VectorMethods>(); triangles = new List <Triangle>(); StreamReader sr = new StreamReader(fileName); string line = sr.ReadLine(); while (String.IsNullOrEmpty(line) == false) { //sprawdzenie połozenia pojedyńczego wektora if (line[0] == 'v') { VectorMethods v = new VectorMethods(); string[] sections = line.Split(' '); v.x = float.Parse(sections[1], CultureInfo.InvariantCulture.NumberFormat); v.y = float.Parse(sections[2], CultureInfo.InvariantCulture.NumberFormat); v.z = float.Parse(sections[3], CultureInfo.InvariantCulture.NumberFormat); vectors.Add(v); } //wektory z przodu (indeksy punktów znajdujących się na froncie) if (line[0] == 'f') { int[] f = new int[3]; string[] sections = line.Split(' '); f[0] = Convert.ToInt32(sections[1]); f[1] = Convert.ToInt32(sections[2]); f[2] = Convert.ToInt32(sections[3]); Triangle t = new Triangle { points = new VectorMethods[] { vectors[f[0] - 1], vectors[f[1] - 1], vectors[f[2] - 1] } }; triangles.Add(t); } line = sr.ReadLine(); } }
public static float ScalarProduct(VectorMethods v1, VectorMethods v2) { float dot = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; return(dot); }
public static float LengthOfVector(VectorMethods v) { return((float)Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z)); }
private void Scene() { Graphics graphics = Graphics.FromImage(bitmap); SolidBrush brush = new SolidBrush(Color.Black); graphics.FillRectangle(brush, 0, 0, bitmap.Width, bitmap.Height); //Tworzenie macierzy rzutowania na 2d float nearDistance = 0.1f; float farDistance = 1000.0f; float angle = 90.0f; //kąt widzenia float aspectRatio = (float)bitmap.Height / (float)bitmap.Width; // wspołczynnik proporcji wyświetlanego ekranu (bitmapy) matProjection = MatrixMethods.Projection(angle, aspectRatio, nearDistance, farDistance); //Tworzenie macierzy rotacji wkierunkach Z, X matRotationZ = MatrixMethods.RotationZ(angleZ); matRotationX = MatrixMethods.RotationX(angleX); List <Triangle> trianglesToRaster = new List <Triangle>(); matTranslation = MatrixMethods.Translation(0.0f, 0.0f, zPosition); //nowa pozycja po rotacji matWorld = MatrixMethods.MatrixIdentity(); matWorld = MatrixMethods.MultiplyMatrix(matRotationZ, matRotationX); matWorld = MatrixMethods.MultiplyMatrix(matWorld, matTranslation); //Vector kierunku poruszania się kamery. VectorMethods vLookDiraction = new VectorMethods(); VectorMethods vUp = new VectorMethods { x = 0, y = 1, z = 0 }; VectorMethods vTarget = new VectorMethods { x = 0, y = 0, z = 5 }; MatrixMethods matCameraRot = MatrixMethods.RotationY(0); vLookDiraction = MatrixMethods.Multiply(matCameraRot, vTarget); vTarget = VectorMethods.AddVectors(vCamera, vLookDiraction); MatrixMethods matCamera = MatrixMethods.CalculatePoint(vCamera, vTarget, vUp); //Tworzenie macierzy widoku kamery MatrixMethods matView = MatrixMethods.InverseMatrix(matCamera); foreach (var triangle in scene.triangles) { Triangle projectedTriangle, transformedTriangle, viewedTriangle; projectedTriangle = new Triangle(3); transformedTriangle = new Triangle(3); viewedTriangle = new Triangle(3); //Tworzenie vektorów transormacji for (int i = 0; i < 3; i++) { transformedTriangle.points[i] = MatrixMethods.Multiply(matWorld, triangle.points[i]); } //Wygląd 'trojkatow' od frontu, z widoku kamery VectorMethods normal, edge1, edge2; edge1 = VectorMethods.SubVectors(transformedTriangle.points[1], transformedTriangle.points[0]); edge2 = VectorMethods.SubVectors(transformedTriangle.points[2], transformedTriangle.points[0]); normal = VectorMethods.CrossProduct(edge1, edge2); normal = VectorMethods.VectorNormalise(normal); // stworzenie wektora z promieniem kamery VectorMethods cameraRay = VectorMethods.SubVectors(transformedTriangle.points[0], vCamera); if (VectorMethods.ScalarProduct(normal, cameraRay) < 0.0f) { //Kierunek światła i cienowanie VectorMethods lightDirection = new VectorMethods { x = 0.0f, y = 1.0f, z = -1.0f }; lightDirection = VectorMethods.VectorNormalise(lightDirection); //wspołczynnik cieniowania float dp = (float)Math.Max(0.1f, VectorMethods.ScalarProduct(lightDirection, normal)); Color c = draw.ChangeColor(Color.Black, dp); //zmiana wektora transormacji korzystając z widoku kamery viewedTriangle.points[0] = MatrixMethods.Multiply(matView, transformedTriangle.points[0]); viewedTriangle.points[1] = MatrixMethods.Multiply(matView, transformedTriangle.points[1]); viewedTriangle.points[2] = MatrixMethods.Multiply(matView, transformedTriangle.points[2]); //rzutowanie wektorow(trojkątów) na 2d for (int i = 0; i < 3; i++) { projectedTriangle.points[i] = MatrixMethods.Multiply(matProjection, viewedTriangle.points[i]); } for (int i = 0; i < 3; i++) { projectedTriangle.points[i] = VectorMethods.DivideByNumber(projectedTriangle.points[i], projectedTriangle.points[i].w); } projectedTriangle.color = c; //przeskalowanie figur na ekranie(współrzedne x,y) VectorMethods vectorOffSetView = new VectorMethods { x = 1, y = 1, z = 0 }; for (int i = 0; i < 3; i++) { projectedTriangle.points[i] = VectorMethods.AddVectors(projectedTriangle.points[i], vectorOffSetView); } //skalowanie do wielkości wyświetlanej bitmapy projectedTriangle.points[0].x *= 0.5f * (float)bitmap.Width; projectedTriangle.points[0].y *= 0.5f * (float)bitmap.Height; projectedTriangle.points[1].x *= 0.5f * (float)bitmap.Width; projectedTriangle.points[1].y *= 0.5f * (float)bitmap.Height; projectedTriangle.points[2].x *= 0.5f * (float)bitmap.Width; projectedTriangle.points[2].y *= 0.5f * (float)bitmap.Height; //Tworzeni listy do sortowania trojkątów projectedTriangle.zValue = (projectedTriangle.points[0].z + projectedTriangle.points[1].z + projectedTriangle.points[2].z) / 3.0f; trianglesToRaster.Add(projectedTriangle); } } //sortowanie trojkatów względem wspołrzednej z trianglesToRaster.Sort((a, b) => b.zValue.CompareTo(a.zValue)); //rysowanie trojkatow foreach (var triangle in trianglesToRaster) { draw.DrawTriangle(triangle, bitmap, triangle.color); pictureBox1.Image = bitmap; } }